Linux PHPからSQL Serverに接続

LinuxクライアントからPHPでSQL Serverに繋ぐ案件が発生した。
条件を整理すると下記の通り。

####クライアント
+ Ubuntu Server 12.04.3 LTS
+ PHP5.3以上

####サーバー
+ SQL Server2008 R2 Express
+ WindowsXP SP3

####特殊な条件
+ apt-get 又はdpkg でインストール可能
+ 日本語テーブル、日本語カラムを難なく読めること
+ 文字化けしないこと
+ 32bitマシン

今回はFreeTDSというライブラリを使って接続することにします。

##FreeTDSで接続
FreeTDSはSybase,Microsoft SQL Serverとデータのやり取りをするためのプロトコルである。
これだけでは、PHPにデータを取得できない。
PHP側にもSybase、Microsoft SQL Serverとデータのやり取りをする関数を入れる。
図解すると下記のようになる。

```:接続イメージ
pdo_dblib(PHP) <-> FreeTDS  <-> SQL Server
```

###インストールするライブラリ

####PHPのSybase関数
* SQL Server,SybaseにアクセスするPHPのライブラリ
* 図ではpdo_dblib(PHP)
* PHPのmssql関数,sybase関数、pdo_dblib関数等が入っています。

#####PHP7.0の場合
* php7.0-sybase

#####PHP5の場合
* php5-sybase

####freetds-common
SQL ServerやSybase Databaseと話すためのProtocol。
TDSはTabular Data Streamの略。


##インストール方法
下記のようにapt-getでインストールします。
今回はソースからコンパイルはしません。

```bash:PHP5の場合
$ sudo apt-get install php5-sybase freetds-common
```

```bash:PHP7の場合
$ sudo apt-get install php7.0-sybase freetds-common
```

##設定方法
freetds.confに設定を追加する。
条件は下記のようになる。

###条件：
####host:
* SQL Server2008 R2 Express
* WindowsXP SP3
* IP: 192.168.0.3
* Database username: sa
* Database Password: password

####client
* Ubuntu 12.04.3 LTS
* LAMP(Linux Apache MySQL PHP)インストール済み  
$ sudo tasksel install lamp-serverでインストールしたものとする。

###freetds.confの場所
freetds.confファイルは、検索すると2つある。
しかし、apache 等のサーバーが使うconfファイルは /etc/freetds/freetds.confである。
freetds.confの場所は以下のコマンドで確認できる。

```bash:tsql
$ tsql -C
プログラム 'tsql' はまだインストールされていません。  
次のように入力することでインストールできます
sudo apt-get install freetds-bin
```

おっと、tsqlがインストールされていませんでしたね。
下記のようにインストールしましょう。

```bash:freetds-bin
$ sudo apt-get install freetds-bin
```

改めてtsqlでfreetds.confの場所を確認します。

```bash:tsql
$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v0.91
             freetds.conf directory: /etc/freetds
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 4.2
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: no
```

freetds.conf directory:/ となっている部分がfreetds.confのある場所です。

freetds.conf - Where it goes を参照
http://www.freetds.org/userguide/freetdsconf.htm


###freetds.confファイル
設定条件もfreetds.confの場所も確認しました。
実際にfreetds.confファイルを編集します。
今回の設定条件だと freetds.conf　は以下のように追加します。


``` freetds.conf:/etc/freetds/freetds.conf
[RDBSERVER]			        ##hostname になる
	host = 192.168.0.3		##接続するDBのIPアドレスを入れる
	port = 1433			##SQL Server2000以降、標準のportは1433
	tds version  =  7.3		##SQL Server2005は7.2  2008は7.3 2012は7.4
	client charset = UTF-8	##Client(Linux)側の文字コードセット
 ```

各パラメーターの詳しい設定項目は下記サイトのTable 3-2. freetds.conf settingsを参照
freetds.conf file　
http://www.freetds.org/userguide/freetdsconf.htm
正しいtds Versionについては下記をご覧ください。
http://www.freetds.org/userguide/choosingtdsprotocol.htm
charset=CP932は不要
http://www.freetds.org/userguide/localization.htm

##設定を確認
tsqlというコマンドで接続できるかどうかを確認します。
接続ができれば設定はできています。

###tsqlで接続
下記のように接続します。

```bash:tsqlで接続
$ tsql -S RDBSERVER -U sa -P password
locale is "ja_JP.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1>
```

-S Servername
freetds.confの[　]で囲まれた部分、
ここでは[RDBSERVER] を指定します。
-U username
データベースのユーザー名
ここでは sa
-P passowrd
データベースのパスワードを指定します。
ここでは password

1> となっていれば接続成功
失敗していればfreetds.confの設定がおかしいかと思います。

下記のサイトを参照して原因を突き止めましょう。

http://www.freetds.org/userguide/confirminstall.htm
http://www.freetds.org/userguide/serverthere.htm#SERVERTHERE.TSQL

###tsqlでSQLを実行
ちなみにtsqlで接続後
下記のようにSQL文を実行します。

```sql:バージョンを表示する特殊なSQL文
1>use master
2>go
1>select @@version
2>go
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (Intel X86) 
	Jun 28 2012 08:42:37 
	Copyright (c) Microsoft Corporation
	Express Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
(1 row affected)
1> quit
```
quitで抜けます。

select @@version
SQL Serverのバージョンを表示する為の特殊なSQL文。
SQL Serverのどのデータベースを指定していても実行できる。
1行だけ表示するのでテストで表示するのにぴったりです。

###日本語テーブルが動くか確認
少し条件を厳しくして、
日本語データベース、日本語テーブル、日本語カラムを作成して表示させてみます。

```sql:日本語データベース作成
1>create database 日本語テーブル達
2>go
```

```sql:日本語データベース選択
1>use 日本語テーブル達
2>go
```

```sql:テーブル作成
1>create table 名前リスト(
2>ID int IDENTITY(1,1) PRIMARY KEY,
3>名前 nvachar(40)
4>)
5>go
```

```sql:データ挿入
1>insert into 名前リスト(名前)
2>values(‘織田　信長’)
3>go
```

```sql:データ選択
1>select * from 名前リスト
2>go
ID	名前
1	織田 信長
(1 row affeted)
1>
```

文字化けしていなければ問題無し。
もし、文字化けしていればfreetds.confのcharsetとclient charsetを見直しましょう。

##PHPからSQL Serverのデータを表示

$ sudo tasksel lamp-server
でインストールされているものとします。

wwwrootに移動します。

```bash:wwwrootに移動
$ cd /var/www/html
```

phpファイルを作成します。

```bash:phpファイル作成
$ sudo vi /var/www/mssql2008R2.php
```

php7.0ではmssql_connectは使えません。
pdo_dblibを使ってください。

```php:mssql2008R2.php
<?php
$server=’RDBSERVER’;
$username='sa';
$password='password';
$connection=mssql_connect($server,$username,$password);

if($connection !=FALSE)
{
        echo "Connection to the database server OK<br />";
}
else
{
        die("Couldn't connect");
}

$query_result=mssql_query("SELECT * FROM [日本語テーブル達].[dbo].[名前リスト]");
$row=mssql_fetch_array($query_result);

if($row !=FALSE)
{
        echo $row['名前'];
}
mssql_free_result($query_result);
mssql_close($connection);
?>
```

PDO_DBlibで接続したサンプル

```php:mssql2008R2.php
<?php
$server=’RDBSERVER’;
$username='sa';
$password='password';

try{
  $pdo=new PDO("dblib:host=$server;dbname=日本語テーブル達",$username,$password);
  $stmt=$pdo->query("SELECT * FROM [日本語テーブル達].[dbo].[名前リスト]");

  print_r($row['名前']);

}catch(PDOExpression $e){
  var_dump($e->getMessage());
}

$pdo=null;

?>
```


ブラウザで表示してみましょう。
url: localhost/mssql2008R2.php


```web:mssql2008R2
Connection to the database server OK
織田 信長
```

##バットノウハウ
以下のようなPHPのMSSQLの関数だけで接続する場合は、
unixODBCもphp_odbc関数のインストールも不要です。

- mssql_connect
- pdo_dblib

##参考サイト等
[Ubuntu Server – Connect to MSSQL via PHP](http://blog.thesysadmins.co.uk/ubuntu-server-connect-to-mssql-via-php.html)
非常にシンプルに書かれているので参考になりました。

[FreeTDS Users Guide](http://www.freetds.org/userguide/)
最終的にはここを読み込みました。
Installing FreeTDSを中心に読んでいました。

[unixODBC+FreeTDS+DBD::ODBCでSQL Serverに接続する」Part2](http://d.hatena.ne.jp/utabou20/20080212/1202797894)
tsqlでsql文が発行できることをここで知りました。