Debian + PHP 5.6からSQL Server 2016へ接続する

SQL Server 2016をインストールしてみました。
SQL Server 2016 ExpressをWindows Server 2012 R2へインストール

Debian 8 + PHP 5.6から接続してみます。


下準備



事前にsampleというデータベースと、テーブルを作成しておきました。

696_01.png

大抵日本語が含まれる場合に躓くので、「日本語テーブル」というテーブル名とし、
「番号(int)」「日本語フィールド(nvarchar(50))」というフィールドを作成しています。


また、SQL Serverの認証モードは「混合」とし、ID、パスワードを用いて
接続できるよう構成しています。

さらに、別のサーバーから接続することになりますので、外部接続を許可しておきます。
SQL Server 2016 + Windows Server 2012 R2 外部接続許可




php5-mssql(php5-sybase)



mssqlというライブラリを使用してSQL Serverに接続することにしました。
http://php.net/manual/ja/book.mssql.php

Debianにはaptでインストールできます。


# apt-get install php5-mssql




ただし、これは「php5-sybase」のエイリアスとなっており、
実際には、freetdsとphp5-sybaseがインストールされます。


# apt-get install php5-mssql
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
Note, selecting 'php5-sybase' instead of 'php5-mssql'
以下の追加パッケージがインストールされます:
freetds-common libsybdb5
以下のパッケージが新たにインストールされます:
freetds-common libsybdb5 php5-sybase
アップグレード: 0 個、新規インストール: 3 個、削除: 0 個、保留: 0 個。
279 kB のアーカイブを取得する必要があります。
この操作後に追加で 714 kB のディスク容量が消費されます。





そのため、以下のコマンドと同義となります。


# apt-get install php5-sybase





※追記
tds versionの指定を行えば、文字コードの変換は不要です。

Debian + PHP 5.6からSQL Server への接続で日本語が文字化けする場合の対応






サンプルプログラム(Mssql 関数)



事前にこんなデータを登録しておきます。

696_02.png


何か設定が不足しているのだと思うのですが、クエリーや結果はms932となっており、
適当にutf8と変換してやりました。

変換しないとこんなエラーになります。


PHP Warning: mssql_query(): message: Invalid object name '日本語テーブル'. (severity 16) in /var/dev/php/sample.php on line 7
PHP Warning: mssql_query(): General SQL Server error: Check messages from the SQL Server (severity 16) in /var/dev/php/sample.php on line 7
PHP Warning: mssql_query(): Query failed in /var/dev/php/sample.php on line 7





サンプルは以下のとおり。


  1. <?php
  2. // クエリーはms932で送る必要あり
  3. function ms932($value) {
  4.     return mb_convert_encoding($value, 'ms932', 'utf-8');
  5. }
  6. // 結果がms932で帰ってくるので、utf8に変換
  7. function utf8($value) {
  8.     return mb_convert_encoding($value, 'utf-8', 'ms932');
  9. }
  10. function conv($ary) {
  11.     $result = array();
  12.     foreach($ary as $k => $v) {
  13.         $result[utf8($k)] = utf8($v);
  14.     }
  15.     return $result;
  16. }
  17. // サーバーに接続
  18. $link = mssql_connect('192.168.1.104:1433', 'sa', 'P@ssw0rd');
  19. mssql_select_db('sample', $link);
  20. // ms932に変換しつつselect実行
  21. $query = 'select * from 日本語テーブル';
  22. $result = mssql_query(ms932($query), $link);
  23. $numRows = mssql_num_rows($result);
  24. echo $numRows . PHP_EOL;
  25. // utf8に変換しつつ結果を表示
  26. while($row = mssql_fetch_array($result)) {
  27.     $row = conv($row);
  28.     
  29.     echo '------'.PHP_EOL;
  30.     echo $row['番号'] . PHP_EOL;
  31.     echo $row['日本語フィールド1'] . PHP_EOL;
  32.     echo '------'.PHP_EOL;
  33. }
  34. // 後始末
  35. mssql_free_result($result);
  36. mssql_close($link);




とりあえずこれで動いてくれました。


# php sample.php
1
------
12
日本語の値
------






PDO



PDOによる接続だとこうなりました。


  1. <?php
  2. function ms932($value) {
  3.     return mb_convert_encoding($value, 'ms932', 'utf-8');
  4. }
  5. // 結果がms932で帰ってくるので、utf8に変換
  6. function utf8($value) {
  7.     return mb_convert_encoding($value, 'utf-8', 'ms932');
  8. }
  9. function conv($ary) {
  10.     $result = array();
  11.     foreach($ary as $k => $v) {
  12.         $result[utf8($k)] = utf8($v);
  13.     }
  14.     return $result;
  15. }
  16. try {
  17.     $pdo = new PDO('dblib:host=192.168.1.104:1433;dbname=sample', 'sa', 'P@ssw0rd');
  18.     $stmt = $pdo->query(ms932("select * from 日本語テーブル"));
  19.     
  20.     while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  21.         $row = conv($row);
  22.         
  23.         echo '------'.PHP_EOL;
  24.         echo $row['番号'] . PHP_EOL;
  25.         echo $row['日本語フィールド1'] . PHP_EOL;
  26.         echo '------'.PHP_EOL;
  27.     }
  28.     
  29.     
  30. } catch (PDOException $e) {
  31.     echo $e->getMessage() . PHP_EOL;
  32. }






文字コードの自動変換



/etc/freetds/freetds.conf の設定値を変更しても、文字コードが自動的に変換されず。


[global]
        # TDS protocol version
;     tds version = 4.2
     tds version = 8
     charset = CP932
     client charset = UTF-8




何を見落としているんだろう...


【参考URL】

sqlsrv driver on Linux?

関連記事

コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
https://symfo.web.fc2.com/

PR

検索フォーム

月別アーカイブ