LINUX.ORG.RU

PHP+UnixODBC+FreeTDS+CentOS проблема с кодировкой

 , ,


0

1

Добрый день!

Необходимо реализовать поиск с выводом результатов с помощью хранимой процедуры. На сервере установлена БД mssql, которая мне не подвластна. Подключение и использование процедуры реализовано с помощью ODBC, сам весь код написан на PHP.

Вычитала, что для реализации в CentOS 7 необходимо установить FreeTDS & UnixODBC и настроить их. Настроить - настроила, однако при выводе результатов поиска русские буквы выводятся в виде знаков вопроса ??????????? , также запрос не понимает ввод русских символов и не выдает результат по ним.

Я прочитала много информации в интернете. В настройках апача указала AddDefaultCherset UTF8, настроила локаль как ru_RU.UTF8.

В файле freetds:

  • [freetds]
  • host = *********
  • port = *******
  • tds version = 7.0
  • user = UID
  • password = PWD
  • client charset = UTF8

Команда tsql выводит корректные данные с нормальными символами, и также корректно понимает запрос русскими символами

Информация о freetds

  • Version: freetds v0.95.81
  • freetds.conf directory: /etc
  • MS db-lib source compatibility: yes
  • Sybase binary compatibility: yes
  • Thread safety: yes
  • iconv library: yes
  • TDS version: 4.2
  • iODBC: no
  • unixodbc: yes
  • SSPI «trusted» logins: no
  • Kerberos: yes
  • OpenSSL: no
  • GnuTLS: yes

И при подключении tsql

  • locale is «ru_RU.UTF8»
  • locale charset is «UTF-8»
  • using default charset «UTF8»

В файле odbcinst прописала необходимые драйвера и в файле odbc к ним корректно подключилась. Команда isql также выводит корректные данные с нормальными символами, и также корректно понимает запрос русскими символами. То есть команды работают и понимают и выводят русские символы.

Однако, на сайте выводятся знаки вопроса. Я пробовала iconv, переделка различных кодировок (с utf-16 на utf-8 выводятся китайские символы, а с некоторыми кодировками текст вообще пропадает). В header также передавала информацию.

Очень долго уже сижу с проблемой кодировки, где моя ошибка и что необходимо исправить для вывода корректных русских символов?

Ответ на: комментарий от bl

Пробовала разные варианты и UTF8 и utf-8 и UTF-8 и вообще другие кодировки

werdenholf
() автор топика

Судя по знакам вопроса, я бы предположил что у вас где-то используется UTF-8(скорее всего его скрипты используют), а где-то cp1251(обычно эту кодировку юзают базы mssql).

Для начала попробуйте добавить cp1251 на сервер с Centos 7, если ранее этой кодировки не было, примерно так

localedef -i ru_RU -f CP1251 /usr/lib/locale/ru_RU.CP1251

после чего в mssql.ini(если он у вас отдельным файлом) или php.ini(если настройки модуля mssql вы добавили в php.ini) добавить

mssql.charset=cp1251

и перезапустить httpd2 или php-fpm, не знаю что именно вы юзаете.

Если данные в базе у вас всё-таки в UTF-8, вместо

mssql.charset=cp1251

нужно указать

mssql.charset=UTF-8

и опять перезапустить httpd или php-fpm.

Если не поможет, возможно стоит в конфиг

freetds

добавить параметры для включения логирования

http://www.freetds.org/userguide/logging.htm

и настроить debug на максимальный уровень, по идее должно быть видно в какой кодировке данные и в какой подключение.

lucentcode ★★★★★
()
Ответ на: комментарий от lucentcode

Итак,первые варианты попробовала Локаль данная уже была установлена в mssql.ini изменила кодировки, да и в php.ini заодно ( поочередно ) В общем это ни к чему не привело, но Вашу мысль я уловила.

C логами увидела вот такое в odbc.trace:

UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

Во freetds.conf

  • iconv.c::local name for ISO-8859-1 is ISO-8859-1
  • iconv.c::local name for UTF-8 is UTF-8
  • iconv.c::local name for UCS-2LE is UCS-2LE
  • iconv.c::local name for UCS-2BE is UCS-2BE
  • iconv.c::setting up conversions for client charset «UTF-8»
  • iconv.c::preparing iconv for «UTF-8» <-> «UCS-2LE» conversion
  • iconv.c::preparing iconv for «ISO-8859-1» <-> «UCS-2LE» conversion
  • iconv.c::tds_iconv_open: done

Получается что мне нужно перекодировать с USC-2LE?

werdenholf
() автор топика
Ответ на: комментарий от werdenholf

Судя по

iconv.c::preparing iconv for «UTF-8» <-> «UCS-2LE» conversion

похоже что freetds приготовился автоматически конвертировать данные с UCS-2LE в UTF-8 и обратно. Смущает только, что он также пригодовился использовать конверсию из ISO-8859-1 в UCS-2LE и обратно. Хотя, вроде ISO-8859-1 - это дефолтная кодировка FreeTDS, определённая на уровне исходного кода, так что скорее всего ничего странного в том, что её перекодировать тоже готов FreeTDS нет...

А что будет, если в самом скрипте добавить в connection string(dsn) параметры

TDS_Version=8.0;ClientCharset=UTF-8

Данные всё также читаются как символы "?"?

lucentcode ★★★★★
()
Ответ на: комментарий от lucentcode

Итак, добавила в глобальную переменную

  • tds version = 8.0
  • client charset = UTF-8

однако, это к сожалению не помогло

В подключении стоит параметр добавления нужной базы из файла odbc.ini, в котором указаны необходимые параметры подключения, включающие в себя TDS_Version=8.0;ClientCharset=UTF-8, однако это тоже не помогает. Или Вы предлагаете написать уже в самом php коде?

werdenholf
() автор топика
Ответ на: комментарий от werdenholf

Решение

Спасибо Вам большое за помощь!!!!

Проблема была достаточно глупой. При повторении своих действий, выяснилось, что freetds не был «подключен» в odbc.ini Возможно, кому то в дальнейшем это поможет.

Через servername необходимо подключить драйвер freetds в odbc.ini Подробнее:

http://www.freetds.org/userguide/odbcombo.htm#FTN.AEN2168

Ошибка глупая, но такое бывает, возможно кому то поможет. Сделала по примеру как на ссылке, что выше, проверила isql, все прекрасно работает.

Парочка еще полезных статей:

werdenholf
() автор топика
Ответ на: комментарий от werdenholf

Верно, если добавление соответствующих параметров в odbc.ini не даёт результата, в строку подключения добавляют TDS_Version=8.0;ClientCharset=UTF-8 прямо в php-коде(в первый параметр вызываемой функции odbc_connect). Если подключение производится в нужной кодировке, значит с кодировкой всё Ок, проблема где-то в конфиге freetds и/или odbc.

lucentcode ★★★★★
()
Ответ на: Решение от werdenholf

Не за что) Что касается проблемы, то такое у всех случается. Сам когда первый раз подобную связку настраивал, тоже забыл добавить нужные параметры в конфиг, и потом долго не мог понять что не так. Повторение своих действий по шагам в таком случае очень помогает. Рад, что у вас всё получилось. И что поделились подробностями решения с сообществом. Уверен, кому-то ваш последний комментарий очень пригодится!

lucentcode ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.