2020年10月13日 リンク切れ更新。内容修正
(1) yum で php-sybase パッケージをインストール
FreeTDS使用 PDOで使う場合、プリフィックスに dblib: を使用する方法
(2) yum で php-sqlsrv パッケージをインストール
MicrosoftのODBC Driver for SQLServer を使用し、PDOで使う場合、プリフィックスに sqlsrv: を使用する方法
(1)は、PHP5系で長らく使われてきた方法です。yumでphp-sybaseをインストールすれば他に何も要りません。リポジトリによっては php-mssql かも。
FreeTDS/php-sybase を使用する時に注意しないといけないのは、主に /etc/freetds.conf で指定する TDSプロトコルのバージョンです。検索したら たまに 8.0にしている記事がありますが、8.0は後方互換性のために定義されていて、実際には 7.1 へのエイリアスとなってます。ドキュメントが更新されたらしく8.0は互換性で残しているが今後削除されるかもしれない、だって。(Choosing a TDS protocol version)
また、SELECTとかで日付・時間の値を取得したとき、返される値がシステムのロケールに依存している場合があります。この場合、/etc/locales.conf を(なければ作成して) ロケール毎に指定するか、php.ini の mssql.datetimeconvert の値をいじる必要があります。
また、プリペアードステートメントを使ったクエリだと、文字列リテラルのとき、自動的にNプレフィックスをつけてくれません。ですので、PDO::prepareで 「N?」という風に付けないといけません。「?」だけでもエラーにはなりませんが、絵文字とか化けます。
(2)は、基本的にPHP 7系以降の方法です。長らく Microsoftは SQLServerのPHPドライバは Windows向けPHPのみサポートしてきましたが、おそらく SQLServer on Linux のリリースに合わせ Linux/MacOS用のPHPドライバ/ODBCドライバもサポートするようになったんじゃないかな?
Windows用PHPと同じように、Linuxの各ディストリビューションのPHPでもフツーに SQLServerへ CRUDできるようになりました。
このページは (2)の方法の備忘録です。
素のCentOS7で、sudo yum install php すると、PHP5.4 がインストールされます(@_@) 5系はもう deprecated ですので、REMIレポジトリを追加し、PHP7をインストールします。。。
CentOS 8もしくは CentOS Stream の場合、標準で PHP7.2がインストールされるのでREMIリポジトリは不要です。7.4とかに上げたい場合は、DNFコマンドで、 dnf module list php とすれば 利用可能な バージョンの一覧がでます。詳しくは DNFコマンドを調べてみてください。
1. Add REMI repository
$ sudo yum install epel-release $ sudo rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm リポジトリ確認 $ yum repolist
2. Install Mircrosoft ODBC Driver for SQLServer
$ sudo su # curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo # exit $ sudo yum remove unixODBC-utf16 unixODBC-utf16-devel $ sudo ACCEPT_EULA=Y yum install msodbcsql17 $ sudo ACCEPT_EULA=Y yum install mssql-tools $ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile $ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc $ source ~/.bashrc
3. Install php and others… by remi repository
もしBaseリポジトリからインストールされたPHPがある場合は、まずそれを削除。
$ sudo yum remove php-* $ sudo yum --enablerepo=remi,remi-php71 install php php-devel php-pdo php-sqlsrv 他のphpモジュールも必要であればインストール。 $ sudo yum --enablerepo=remi,remi-php71 install unixODBC-devel php-mbstring php-gd php-cli
CentOS8では標準でPHP7.2がインストールされますので、REMIリポジトリは必要ありません。
ただし、DNF(YUM)ではphp-sqlsrvをインストールできないので、pecl を利用しないといけません。
詳しくはマイクロソフトのサイトを参照した方がよろしいかと。
https://www.microsoft.com/en-us/sql-server/developer-get-started/php/rhel/step/2.html
接続するときの注意事項。
- 接続文字列でSQLServerのサーバー名を指定する時、SQLServerインスタンスの着信ポートが1433以外の場合は、コロン(:)じゃなくて、カンマで区切って指定。これハマった💦
- SQLServer 接続マネージャ で TCPを有効にする。私がSQLServerをインストールした時、デフォルトでは無効になってました。
- OS(普通はWindows Server)のファイヤーウォールで着信ポートを許可する事。
あとは普通に接続。テーブル作成はWindowsでSQLServer Management Studio(SSMS)を使うとラクですので、適当にテーブルを作成し、そのテーブルに対して「テーブルをスクリプト化 ⇒ 新規作成 ⇒ ファイル」でSQLファイルとして保存しておく。保存したらそのテーブルは一旦削除(別にしなくてもいいけど)。
<?php //SQL Serverの着信ポートを SQLServer構成マネージャで確認しておく。1433以外の場合はカンマで区切って指定 $pdo = new PDO('sqlsrv:Server=localhost,49494;Database=Sample','sa','xxxxxx'); //(必要なら)テーブル作成 $sql = file_get_contents(<上で作ったSQLファイルのパス>); $res = $pdo->exec($sql); var_dump($res); //UTF-8なCSVファイルをDBに登録するための用意 // ここでは1行に3つのセル(id,name,desc 等)があるCSVを仮定してます。 // 改行を含むセルがあるCSVファイルの場合、SplFileObject 以外は使わない方が良いと思う。 $csv = new SplFileObject(<csv file path>,'r'); $csv->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY); //Create $sth = $pdo->prepare('INSERT INTO tbl_sample VALUES(?,?,?)'); $sth->bindParam(1,$param1,PDO::PARAM_STR); $sth->bindParam(2,$param2,PDO::PARAM_INT); $sth->bindParam(3,$param3,PDO::PARAM_STR); foreach($csv as $row) { list($param1,$param2,$param3) = $row; $sth->execute(); } //Read $sth = $pdo->query('SELECT * FROM INFORMATION_SCHEMA.TABLES'); $rows = $sth->fetchAll(PDO::FETCH_ASSOC); print_r($rows); //Update $sth = $pdo->prepare('UPDATE tbl_sample SET column2=?,column3=? WHERE column1 = ?'); $sth->bindValue(1,2,PDO::PARAM_INT); $sth->bindValue(2,'column value3',PDO::PARAM_STR); $sth->bindValue(3,'column value 1',PDO::PARAM_STR); $res = $sth->execute(); var_dump($res); //Delete $res = $pdo->exec("DELETE FROM tbl_sample WHERE column1 = N'column1 value'"); var_dump($res);
【タイプミス修正】2020年3月18日