Help us understand the problem. What is going on with this article?

Linux PHPからSQL Serverに接続

More than 3 years have passed since last update.

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でインストールします。
今回はソースからコンパイルはしません。

PHP5の場合
$ sudo apt-get install php5-sybase freetds-common
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の場所は以下のコマンドで確認できる。

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

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

freetds-bin
$ sudo apt-get install freetds-bin

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

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 は以下のように追加します。

/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で接続

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

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文
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行だけ表示するのでテストで表示するのにぴったりです。

日本語テーブルが動くか確認

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

日本語データベース作成
1>create database 日本語テーブル達
2>go
日本語データベース選択
1>use 日本語テーブル達
2>go
テーブル作成
1>create table 名前リスト(
2>ID int IDENTITY(1,1) PRIMARY KEY,
3>名前 nvachar(40)
4>)
5>go
データ挿入
1>insert into 名前リスト(名前)
2>values(‘織田 信長’)
3>go
データ選択
1>select * from 名前リスト
2>go
ID  名前
1   織田 信長
(1 row affeted)
1>

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

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

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

wwwrootに移動します。

wwwrootに移動
$ cd /var/www/html

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

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

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

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で接続したサンプル

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

mssql2008R2
Connection to the database server OK
織田 信長

バットノウハウ

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

  • mssql_connect
  • pdo_dblib

参考サイト等

Ubuntu Server – Connect to MSSQL via PHP
非常にシンプルに書かれているので参考になりました。

FreeTDS Users Guide
最終的にはここを読み込みました。
Installing FreeTDSを中心に読んでいました。

unixODBC+FreeTDS+DBD::ODBCでSQL Serverに接続する」Part2
tsqlでsql文が発行できることをここで知りました。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away