2008年2月 6日

[PHP-users 33237] Re:PHP5+MSSQLSERVER2005での中国語の取得について

お世話になります。

以前に標記タイトルでお力をお借りして解決したのですが、
kanonbellさまにお教えいただいた方法で試してみたところ、
うまく中国語が抽出できませんでした。

================================================================================
$db = &ADONewConnection("ado_mssql");

$db->charpage = 65001; // UTF-8

$myDSN="PROVIDER=MSDASQL;DRIVER={SQLServer};" .
"SERVER=IPアドレス\インスタンス名;DATABASE=test;UID=sa;PWD=xyz;";

$db->Connect($myDSN);

$rs = $db->Execute("select * from test");
$arr = $rs->GetArray();
print_r($arr);
================================================================================

上記を実行すると、データベースへの接続、データの抽出は出来るのですが
nvarchar型に格納されている全角文字が文字化けして表示されてしまいます。

ちなみに以下のように
 new COM('ADODB.Connection', NULL, CP_UTF8);
自前でADODBオブジェクトを生成してデータの抽出を行った場合は
nvarchar型に格納されている全角文字が表示されております。

ADOdb経由での記述に何か誤りがあるのでしょうか。
よろしくお願いいたします。

kanonbell wrote:
> こんばんは。
>
> 私にとっても懸念事項だったので、調べてみました。
> PHP+MSSQLの環境は文字については正直厳しいですね。。
> 扱うのが日本語(+ANSI)のみだったら問題ないんですが。
>
> 結果からいうと、「ニーハオ」って中国語と「あいうえお」という日本語をNVARCHARな
> カラムに記述しているレコードを正常に表示できました。
> 表示その他は基本的にUTF-8です。
> DBの照合順序を変えたりもしてみましたが、表示には影響しませんでした。
>
> 使うのはADO。
> データベース仮想化レイヤのADOdbではなく、WindowsのCOM APIの、
> データベースアクセスに良く使うやつです。
> PHPにはCOM関数があるのでそれ使ってもいいんですが、今回はADOdb経由で
> 使ってみました。楽だし。
>
> http://jp.php.net/manual/ja/class.com.php
> オプション扱いの引数にcodepageがあるので、65001(UTF-8)を指定します。
>
> include('adodb.inc.php');
> $conn = &ADONewConnection('ado_mssql');
> $conn->charpage = 65001
>   :
> って感じになります。
>
> 取得したレコードセットは普通にUTF-8で入っているので、特に文字コード変換などを
> 行わなくてもそのまま表示できました。
>
> > Windows Server 2003
> > HTTPD2.2系の最新
> > PHP5.2系の最新
> > MS SQLSERVER 2005
>
> 試した環境自体は全く同じです。
> MSSQLはローカル。
> NVARCHARなカラムに、Management Studio上から直接日本語と中国語を
> 打ち込んでいます。
> 当然ながらManagement Studio上からは正常に表示できます。
> UTF-8で表示しているASP上でも、正常に表示できます。
>
> 以下は蛇足。
>
> > いろいろと調べてみたところ、
> > 抽出された文字列がSJISであるため
> > UTF-8への変換が必要であることがわかりました。
>
> まあそうなんですが、ちょっと補足。
> MSSQL2005は内部的にUCS-2(UCS-2LE?)で文字列を保持しています。
> このデータをデータベースクライアントに渡す際に文字コードの変換が発生して
> いるみたいなんですね。
> BOL読む限り、「ユニコードに対応していない場合データベースクライアントが
> 相手だったら、相手のコードページにあわせて変換する」ってなことが書いてある
> ようですし。
>
> > 試しに、データベースへの接続を思い当たる3つの方法
> > ・mssql関数
> > ・PDO_ODBC
> > ・ADBdb
> > にて行ってみましたが、どれも同じ結果になりました。
>
> ADOdbは仮想化レイヤであってドライバ選べるので。。
>
> mssql関数が使用するデータベースクライアントはDB-Libraryで、ものすごく古く、
> MSSQL2005ではまだ使えるもののサポートの打ち切りが明言されています。
> PHP+MSSQLで使う分には多分一番高機能なのが泣かせますが。。
> このDBクライアントはユニコードに対応していないので、強制的にこのクライアントが
> 存在するWindowsのコードページ(つまりWebサーバのコードページ)である
> SJISに変換されます。他言語版Windowsだったら多分他のになるでしょう。
> この辺はカラムの照合順序を変えるとSJIS以外の文字コードに変換されることも
> あるので、実装が謎だったりしますが。
> インド系の照合順序にしてみたら、DB-Libraryはユニコード対応してないから
> 無理だよ的エラーが出たりもしました。
>
> ODBCはバージョンによるもののユニコードに対応しているんですが、PHP側の
> ODBCドライバがOSのコードページをそのまま申請しちゃうのかな?
> DB-Libraryと同じようにSJIS変換がかけられてしまい、どうにもダメでした。
> ODBCの設定で文字コード変換を無効にしてもだめですね。
>
> SQL Server 2005 Driver for PHP CTPは結局試さなかったんですが、すでに
> お試しになってるようですね。
> PHP+MSSQLでのまともなデータベースクライアントが風前の灯って感じだったので、
> これには少々期待してるんですが、更新されるのかなあ。。
> DATETIME型まだ使えないらしいですが。
>
> MSSQL関数の説明ページには、文字コードの強制変換の問題を回避するやり方
> として、バイナリを利用するやり方がコメントの形で解説されています。
> ADOdbのADOドライバ(ラッパー)は軽く見た感じ最小限度の機能が用意されている
> 程度で不安を感じないでもなかったので、そちらのやり方も参考にしておくと良いかも
> しれません。
> _______________________________________________
> PHP-users mailing list PHP-users@xxxxx
> http://ml.php.gr.jp/mailman/listinfo/php-users
> PHP初心者のためのページ - 質問する前にはこちらをお読みください
> http://oldwww.php.gr.jp/php/novice.php3
_______________________________________________
PHP-users mailing list PHP-users@xxxxx
http://ml.php.gr.jp/mailman/listinfo/php-users
PHP初心者のためのページ - 質問する前にはこちらをお読みください
http://oldwww.php.gr.jp/php/novice.php3

投稿者 xml-rpc : 2008年2月 6日 14:31
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/69501
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。