Как использовать ODBC PHP PDO с символами SQL Server и Unicode?

PHP PDO ODBC, похоже, не в состоянии хранить символы NVARCHAR (UTF-16) без некоторого ручного кодирования. Похоже, что это довольно распространенная «ошибка» во всем Интернете, и ни у кого, похоже, нет окончательного решения.

Как воспроизвести ошибку

  1. Попробуйте вставить следующие японские символы с помощью PDO: こんにちは (Значит привет)
  2. Следующее будет храниться в вашей базе данных: ã“ã‚“ã«ã¡ã¯
  3. Затем извлеките его через PDO и распечатайте на экране, вы получите: こんにちは

Это не так плохо, но и не хорошо. PHP работает, но когда у вас есть другие приложения, которые не в PHP и которые обращаются к этой информации из вашей базы данных, они получат неверную строку: ã“ã‚“ã«ã¡ã¯,

В идеале вы хотели бы иметь こんにちは везде.

Симптом

Кажется, что PDO не имеет никакого понятия о NVARCHAR, то есть символах, которые кодируются с использованием 16 битов. Фактически, все, что вы передаете или извлекаете из SQL SERVER через PDO, будет иметь размер 8 бит. Как это «доказать»? Вот :

  1. Вы начинаете со своей японской нити こんにちは,

Сначала вы должны знать, что PHP рассматривает строку как двоичную и что (если она установлена ​​таким образом) будет хранить их в UTF-8.

Так что, если мы посмотрим на двоичное представление こんにちは, ты получишь E38193E38293E381ABE381A1E381AF который также является двоичным представлением, которое SQL SERVER даст вам для ã“ã‚“ã«ã¡ã¯, (зависит от вашего сопоставления)

  1. Далее, давайте поместим его в UTF-16, потому что это формат NVARCHAR.

    $ utf16_string = mb_convert_encoding (‘こ ん に ち は’, ‘UTF-16LE’);

Следующее изменит двоичное представление в PHP こんにちは в 533093306B3061306F30 который является именно двоичным представлением こんにちは в SQL SERVER NVARCHAR.

  1. Затем попробуйте сохранить его в SQL через PDO, и вы получите следующее: S0“0k0a0o0

Бинарное представление SQL SERVER S0“0k0a0o0 в VARCHAR есть 533093306B3061306F30 который также является двоичным представлением こんにちは в NVARCHAR.

Грязный раствор

Вы можете использовать следующее для сохранения и извлечения данных Unicode в SQL SERVER через PDO ODBC, но это уродливо …

  1. Вы хотите преобразовать данные в точно такое же двоичное представление, как SQL SERVER NVARCHAR
    будет хранить его

    mb_convert_encoding (‘こ ん に ち は’, ‘UTF-16LE’);

  2. Вы хотите получить его как двоичный файл на стороне SQL SERVER, а затем преобразовать его в NVARCHAR.

    @binary VARBINARY (40)
    SELECT @string = CONVERT (NVARCHAR (20), @binary);

  3. На данный момент у вас есть こんにちは в вашей базе данных. Чтобы получить его, вы хотите отправить его в PHP как двоичный файл

  4. Как только вы получите двоичный файл в PHP, PHP уже преобразует его в шестнадцатеричную строку … Итак, вы хотите преобразовать шестнадцатеричную строку в двоичную, а затем изменить кодировку с utf-16 на utf-8.

    $ result = mb_convert_encoding (hex2bin ($ string), ‘UTF-8’, ‘UTF-16LE’);

И ты вернешься со своим こんにちは когда вы откликаетесь на свою веб-страницу.

По сути, это то, что драйвер SQL должен делать для меня вместо того, чтобы я делал это вручную.

Я забыл что-то настроить или я должен сделать это вручную?

3

Решение

Нет, я не думаю, что вы забыли что-то настроить. На самом деле, ваше объяснение — лучшее, что я нашел на данный момент в отношении давних «проблем» между драйверами ODBC для PHP и Microsoft. Эти вопросы особенно озадачивают, учитывая, что Страница PDO_ODBC говорит:

В Windows PDO_ODBC … является рекомендуемым драйвером для подключения к базам данных Microsoft SQL Server.

Тем не менее, на Windows они также предлагают PDO_SQLSRV который на самом деле, кажется, работает правильно.

Похоже, что PDO_ODBC «не имеет никакого понятия о NVARCHAR», а не PDO в целом.

(Подобные проблемы возникают при попытке использовать PHP с Microsoft Access ODBC, если задействованы символы Юникода)

Вывод: поддержка PHP для ODBC по-прежнему остается беспорядком, по крайней мере в том, что касается баз данных Microsoft.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]