15

DomDocumentを使用してPHPでXMLファイルを生成していますが、アジアの文字を処理する必要があります。pdo_mssqlドライバーを使用してMSSQL2008サーバーからデータをプルし、XML属性値にutf8_encode()を適用します。特殊文字がない限り、すべてが正常に機能します。

サーバーはMSSQLServer2008SP3です。

データベース、テーブル、および列の照合はすべてSQL_Latin1_General_CP1_CI_ASです。

PHP5.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では、アジアの文字を正しく表示できます。

上記のすべての詳細を考慮して、データをどのように処理する必要がありますか?

4

7 に答える 7

24

私はそれを解決する方法を見つけたので、うまくいけば、これは誰かに役立つでしょう。

まず、SQL_Latin1_General_CP1_CI_ASは、CP-1252とUTF-8の奇妙な組み合わせです。基本的なキャラクターはCP-1252なので、UTF-8だけですべてが機能しました。アジアおよびその他のUTF-8文字は2バイトでエンコードされ、php pdo_mssqlドライバーはさまざまな長さの文字を嫌うようであるため、(nvarcharではなく)varcharに対してCASTを実行し、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);
于 2012-04-13T15:21:12.383 に答える
2

この投稿が古いことは知っていますが、私にとって機能するのはiconv( "CP850"、 "UTF-8 // TRANSLIT"、$ var);だけでした。SQL_Latin1_General_CP1_CI_AIでも同じ問題が発生しました。おそらく、SQL_Latin1_General_CP1_CI_ASでも機能します。

于 2013-09-25T19:27:24.683 に答える
2

あなたはそう試すことができます:

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>");
}
于 2014-06-17T23:19:49.377 に答える
1

私にとって、上記のいずれも直接的な解決策ではありませんでしたが、上記の解決策の一部を使用しました。これはベトナム語のアルファベットで私のために働いた。この投稿に出くわし、上記のいずれもうまくいかない場合は、次のことを試してください。

    $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コードを取得していました。修正するには、json_encodeで送信する前に、文字列でhtml_entity_decode()を使用するだけです。

于 2017-02-28T19:13:56.517 に答える
1

クレイジーなものは必要ありません。照合SQL_Latin1_General_CP1_CI_AS文字エンコードは次のとおりです。Windows-1252

これは私にとって完璧に機能します:$str = mb_convert_encoding($str, 'UTF-8', 'Windows-1252');

于 2019-12-26T15:19:04.680 に答える
0

デフォルトでは、データの送受信にPDO使用します。PDO::SQLSRV_ENCODING_UTF8

現在の照合がである場合、代わりに現在のシステムエンコーディングを使用することを通知するようにLATIN1指定PDO::SQLSRV_ENCODING_SYSTEMしてみましたか?PDOUTF-8

PDO::SQLSRV_ENCODING_BINARYバイナリ形式でデータを返すwhichを使用することもできます(データを転送するときにエンコードや変換は行われません)。このように、あなたはあなたの側で文字エンコーディングを扱うことができます。

その他のドキュメントはこちら:http ://ca3.php.net/manual/en/ref.pdo-sqlsrv.php

于 2012-04-12T14:34:40.013 に答える
0

答えてくれてありがとう@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']);

于 2015-09-12T04:59:09.177 に答える