Кодирование SQL_Latin1_General_CP1_CI_AS в UTF-8

Я создаю XML-файл с PHP, используя DomDocument, и мне нужно обрабатывать азиатские символы. Я извлекаю данные с сервера MSSQL2008 с помощью драйвера pdo_mssql и применяю utf8_encode () к значениям атрибутов XML. Все работает отлично, пока нет специальных символов.

Сервер – это MS SQL Server 2008 SP3

Сборка базы данных, таблицы и столбца – это все SQL_Latin1_General_CP1_CI_AS

Я использую PHP 5.2.17

Вот мой объект PDO:

$pdo = new PDO("mssql:host=MyServer,1433;dbname=MyDatabase", user123, password123); 

Мой запрос является базовым SELECT.

Я знаю, что хранение специальных символов в столбцах SQL_Latin1_General_CP1_CI_AS невелик, но в идеале было бы неплохо заставить его работать, не меняя его, потому что другие не-PHP-программы уже используют этот столбец, и он отлично работает. В SQL Server Management Studio я правильно вижу азиатские символы.

Учитывая все вышеперечисленные детали, как мне обрабатывать данные?

Related of "Кодирование SQL_Latin1_General_CP1_CI_AS в UTF-8"

Я нашел, как его решить, поэтому, надеюсь, это будет полезно кому-то.

Во-первых, SQL_Latin1_General_CP1_CI_AS – странное сочетание CP-1252 и UTF-8. Основными персонажами являются CP-1252, поэтому я все-таки должен был сделать UTF-8, и все сработало. Асимвольные и другие символы UTF-8 закодированы на 2 байта, и драйвер php pdo_mssql, кажется, ненавидит переменные длины символов, поэтому он, похоже, делает CAST для varchar (вместо nvarchar), а затем все 2 байтовых символа становятся вопросительными знаками (' ? ').

Я исправил его, выставив его в двоичный файл, а затем перестроил текст с помощью php:

 SELECT CAST(MY_COLUMN AS VARBINARY(MAX)) FROM MY_TABLE; 

В php:

 //Binary to hexadecimal $hex = bin2hex($bin); //And then from hex to string $str = ""; for ($i=0;$i<strlen($hex) -1;$i+=2) { $str .= chr(hexdec($hex[$i].$hex[$i+1])); } //And then from UCS-2LE/SQL_Latin1_General_CP1_CI_AS (that's the column format in the DB) to UTF-8 $str = iconv('UCS-2LE', 'UTF-8', $str); 

Я знаю, что этот пост старый, но единственное, что работает для меня, это iconv («CP850», «UTF-8 // TRANSLIT», $ var); У меня были те же проблемы с SQL_Latin1_General_CP1_CI_AI, возможно, он работает и для SQL_Latin1_General_CP1_CI_AS.

Вы можете попробовать:

 header("Content-Type: text/html; charset=utf-8"); $dbhost = "hostname"; $db = "database"; $query = "SELECT * FROM Estado ORDER BY Nome"; $conn = new PDO( "sqlsrv:server=$dbhost ; Database = $db", "", "" ); $stmt = $conn->prepare( $query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED, PDO::SQLSRV_ENCODING_SYSTEM) ); $stmt->execute(); while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ) { // CP1252 == code page Latin1 print iconv("CP1252", "ISO-8859-1", "$row[Nome] <br>"); } 

По умолчанию PDO использует PDO::SQLSRV_ENCODING_UTF8 для отправки / получения данных.

Если ваш текущий результат равен LATIN1 , попробовали ли вы специфицировать PDO::SQLSRV_ENCODING_SYSTEM чтобы PDO знал, что вы хотите использовать текущую системную кодировку вместо UTF-8 ?

Вы даже можете использовать PDO::SQLSRV_ENCODING_BINARY который возвращает данные в двоичной форме (при передаче данных не происходит кодирования или перевода). Таким образом, вы можете обрабатывать кодировку символов на вашей стороне.

Больше документации здесь: http://ca3.php.net/manual/en/ref.pdo-sqlsrv.php

Спасибо @SGr за ответ.
Я нашел лучший способ сделать это:

SELECT CAST(CAST(MY_COLUMN AS VARBINARY(MAX)) AS VARCHAR(MAX)) as MY_COLUMN FROM MY_TABLE;
а также попробуйте:
SELECT CAST(MY_COLUMN AS VARBINARY(MAX)) as MY_COLUMN FROM MY_TABLE;

И в PHP вы должны просто преобразовать его в UTF-8:

$string = iconv('UCS-2LE', 'UTF-8', $row['MY_COLUMN']);

Для меня ни одно из вышеперечисленных не было прямым решением, хотя я использовал некоторые части вышеперечисленных решений. Это работало для меня с вьетнамским алфавитом. Если вы столкнулись с этим сообщением, и ни одно из вышеперечисленных действий для вас не поможет, попробуйте:

  $req = "SELECT CAST(MY_COLUMN as VARBINARY(MAX)) as MY_COLUMN FROM MY_TABLE"; $stmt = $conn->prepare($req); $stmt->execute(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $str = pack("H*",$row['MY_COLUMN']); $str = mb_convert_encoding($z, 'HTML-ENTITIES','UCS-2LE'); print_r($str); } 

И небольшой бонус – мне пришлось json_encode эти данные и был (duh) получать html-код вместо специальных символов. для исправления просто используйте html_entity_decode () для строк перед отправкой с помощью json_encode.