PHP + SQL Server - Как установить кодировку для подключения? - PullRequest
25 голосов
/ 24 августа 2009

Я пытаюсь сохранить некоторые данные в базе данных SQL Server через php.

Проблема в том, что специальные символы не конвертируются должным образом. Кодировка моего приложения iso-8859-1 сервер использует windows-1252.

Преобразование данных перед вставкой не помогает, похоже, что некоторые конверсия продолжается.

Запуск SQL-запроса 'set char_convert off' также не помогает.

Кто-нибудь знает, как мне заставить это работать?

РЕДАКТИРОВАТЬ: Я пробовал ini_set ('mssql.charset', 'windows-1252'); также, но никакого результата с этим тоже нет.

Ответы [ 13 ]

23 голосов
/ 24 августа 2012

Клиентская кодировка необходима, но не достаточна:

ini_set('mssql.charset', 'UTF-8');

Я два дня искал, как вставить данные UTF-8 (из веб-форм) в MSSQL 2008 через PHP. Я читаю везде, что вы не можете, вам нужно сначала конвертировать в UCS2 (как рекомендует решение Cypher). В Windows SQLSRV считается хорошим решением, которое я не смог попробовать, так как я работаю на Mac OSX.

Однако в руководстве FreeTDS (которое PHP mssql использует в OSX) сказано добавить букву «N» перед открывающей цитатой:

mssql_query("INSERT INTO table (nvarcharField) VALUES (N'űáúőűá球最大的采购批发平台')", +xon);

Согласно этому обсуждению, символ N указывает серверу конвертировать в Unicode. https://softwareengineering.stackexchange.com/questions/155859/why-do-we-need-to-put-n-before-strings-in-microsoft-sql-server

5 голосов
/ 06 марта 2012

У меня была такая же проблема, и ini_set('mssql.charset', 'utf-8') не работал для меня. Тем не менее, он работал в верхнем регистре:

ini_set('mssql.charset', 'UTF-8');
5 голосов
/ 13 февраля 2012

Предлагаю взглянуть на следующие моменты:

  1. Убедитесь, что столбцы, в которых хранится информация: nchar или nvarchar , поскольку char и nvarchar не поддерживают UCS-2 (SQLServer не хранится в формате UTF-8 (кстати)
  2. Если вы подключаетесь с библиотекой / расширением mssql для PHP, запустите: ini_set('mssql.charset', 'utf-8');, поскольку нет функции с аргументом charset ( connect, запрос и т. Д.)
  3. Убедитесь, что кодировка вашего браузера также установлена ​​на UTF-8
4 голосов
/ 06 февраля 2015

Если ini_set('mssql.charset', 'UTF-8'); не помогает И у вас нет прав root для изменения общесистемного файла freetds.conf, вот что вы можете сделать:

1. Настройка /your/local/freetds.conf Файл:

[sqlservername]
    host=192.168.0.56
    port=1433
    tds version=7.0
    client charset=UTF-8

2. Убедитесь, что DSN вашего подключения использует имя сервера, а не IP:

'dsn' => 'dblib:host=sqlservername;dbname=yourdb

3. Сделайте FreeTDS для использования вашего локального файла freetds.conf в качестве непривилегированного пользователя из сценария php через переменные env:

putenv('FREETDSCONF=/your/local/freetds.conf');
4 голосов
/ 20 августа 2013

Если вы используете протокол TDS версии 7 или выше, ВСЕ соединения по проводам преобразуются в UCS2. Сервер преобразует из UCS2 во все, что установлено для сопоставления таблицы или столбца, если только столбец не nvarchar или ntext. Вы можете хранить UTF-8 в обычном varchar или тексте, вам просто нужно использовать версию протокола TDS ниже 7, например 6.0 или 4.2. Единственным недостатком этого метода является то, что вы не можете запрашивать любые таблицы nvarchar, ntext или sys. * (Я думаю, что вы также не можете выполнять какие-либо CAST ()) - так как сервер отказывается отправлять все, что может быть преобразовано UTF-8 для любого клиента, использующего версию протокола ниже 7.

Невозможно избежать преобразования наборов символов при использовании протокола TDS версии 7 или выше (примерно эквивалентно MSSQL 2005 или новее).

2 голосов
/ 03 ноября 2014

Для меня редактирование этого файла:
/etc/freetds/freetds.conf
... и поменял / установил параметр 'tds version' на '7.0'. Отредактируйте ваш freetds.conf и попробуйте изменить этот параметр для вашей конфигурации сервера (или глобальной).

Это будет работать даже без перезапуска Apache.

2 голосов
/ 15 марта 2011

Мне повезло в аналогичной ситуации (с использованием соединения PDO ODBD) с использованием следующего кода для преобразования кодировки перед выводом на печать:

$data = mb_convert_encoding($data, 'ISO-8859-1', 'windows-1252');

Мне пришлось вручную установить кодировку источника, потому что она была ошибочно сообщена как 'ISO-8859-1' mb_detect_encoding().

Мои данные также сохранялись в базе данных другим приложением, поэтому я могу оказаться в уникальной ситуации, хотя надеюсь, что это поможет!

1 голос
/ 17 декабря 2018

В моем случае это сработало после того, как я добавил параметры CharacterSet в опцию sqlsrv_connect() подключения.

$connectionInfo = array( 
        "Database"=>$DBNAME,
        "ConnectionPooling"=>0,
        "CharacterSet"=>"UTF-8"
);
$LAST_CONNECTION = sqlsrv_connect($DBSERVER, $connectionInfo);

См. Документацию здесь: https://docs.microsoft.com/en-us/sql/connect/php/connection-options?view=sql-server-2017

0 голосов
/ 01 марта 2019

Я не заметил, чтобы кто-то упоминал другой способ преобразования результатов из базы данных MSSQL. Старый добрый iconv() функция:

iconv (string $in_charset, string $out_charset, string $str): string;

В моем случае все остальное не смогло обеспечить значимое преобразование, кроме этого при получении результатов. Конечно, это делается внутри цикла синтаксического анализа результатов запроса - от CP1251 до UTF-8:

foreach ($records as $row=>$col) {
    $array[$row]['StatusName'] = iconv ('CP1251', 'UTF-8' , $records[$row]['StatusName']);
}

Ужасно, но это работает.

0 голосов
/ 24 марта 2017

Просто добавление ini_set('mssql.charset', 'UTF-8'); не помогло мне в моем случае. Я должен был указать набор символов UTF-8 в столбце:

$age = 30;  
$name = utf8_encode("Joe");    

$select = sqlsrv_query($conn, "SELECT * FROM Users WHERE Age = ? AND Name = ?",
    array(array($age), array($name, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('UTF-8')));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...