(2012/09/20) PHP から Oracle を使う際に PDO_OCI を使いたかったのですが、RPM パッケージを提供してくれるところを見つけられなかったので自前構築しました。その時のメモです。
例示におけるプラットフォームには CentOS 6.3(64bit) を使っています。他の OS やディストリビューションをお使いの方は、yumなど固有のコマンド名を適宜読み替えてください。
また後述のように、PDO_OCI はメンテナーが不在で開発が止まっているようで、ステータスも Experimental のままです。手元の環境ではパッチを当ててなんとか運用していますが、自己責任でお使いください。
PDO(PHP Data Objects)は PHP 5.1 から標準でバンドルされている、各種データベースへのアクセスを抽象化するインターフェースです。これを使うと複数の RDBMS に対して同じ方法でアクセスできます。これを使う場合は php-pdo というパッケージをインストールします。
PDO を使うにしろ使わないにしろ、データベースを使う限りは下位のネイティブドライバーが必要です。たとえば PHP で PostgreSQL を使う場合、php-pgsql パッケージを導入します。php-pgsql の場合はその中に pdo_pgsql モジュールが含まれているので、PostgreSQL の場合はネイティブドライバー(*1)経由でも PDO 経由でもそのまま使えます。
hotta:~$ rpm -ql php-pgsql
/etc/php.d/pdo_pgsql.ini
/etc/php.d/pgsql.ini
/usr/lib64/php/modules/pdo_pgsql.so
/usr/lib64/php/modules/pgsql.so
ところが RDBMS として Oracle を使いたい場合は、ライセンスの関係なのか、php-oracle のようなパッケージは公式のリポジトリでは提供されていないようです(*2)。ただ yum にこだわらなければネイティブドライバーとして Oracle Database Instant Client を利用できます。これは Oracle から無償で公開されているライブラリとユーティリティーです。
(*1)…pg_connect() 関数で接続する方式
(*2)…Oracle Linux 用の PHP パッケージというのはあるようで、一応 RHEL にも入ると書いてありますが、どうも現状では RHEL5 相当のようです。また、残念ながら PDO_OCI は Experimental ということで同梱されていないようです。
まずはベースとなる php を導入します。ここに記載してあるすべてを入れる必要はありませんが、後から別パッケージの導入やビルド時に必要になるので、少なくとも php-pear / php-devel / php-pdo あたりは入れておく必要があるでしょう。
PDO_OCI とは直接関係はありませんが、CentOS6 で posix 関数や IPC(Inter-Process Communication - システム間通信)関数を使う場合は php-process も必要なので、ついでに入れてあります。
root:~# yum install php php-devel php-ldap php-cli php-pdo php-common \ php-xmlrpc php-mbstring php-soap php-mysql php-pear php-pgsql php-process root:~# rpm -qa|grep ^php php-common-5.3.3-14.el6_3.x86_64 php-devel-5.3.3-14.el6_3.x86_64 php-mbstring-5.3.3-14.el6_3.x86_64 php-cli-5.3.3-14.el6_3.x86_64 php-5.3.3-14.el6_3.x86_64 php-mysql-5.3.3-14.el6_3.x86_64 php-pear-1.9.4-4.el6.noarch php-xmlrpc-5.3.3-14.el6_3.x86_64 php-soap-5.3.3-14.el6_3.x86_64 php-pdo-5.3.3-14.el6_3.x86_64 php-ldap-5.3.3-14.el6_3.x86_64 php-process-5.3.3-14.el6_3.x86_64 php-pgsql-5.3.3-14.el6_3.x86_64
Instant Client Downloads for Linux x86-64のページから必要なパッケージをダウンロードしてから導入してください。今回は以下のものをインストールしました。
root:~# rpm -Uvh oracle* root:~# rpm -qa|grep ^oracle oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64 oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64 oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64
各アプリケーションが Oracle ライブラリを自動でロードできるようにするためのおまじないを入れておきます。
root:~# echo /usr/lib/oracle/11.2/client64/lib > /etc/ld.so.conf.d/oracle-instant-client.conf
OCI(Oracle Call Interface)は Oracle とのネイティブ接続を行うための API です。PDO_OCI は PDO の配下で OCI 接続を実現するためのドライバです。例によって標準の yum リポジトリにはないので PECL(PHP Extension Community Library) で入れようとしましたが、サポートが追いついていないようです。なお、pecl コマンドは php-pear パッケージに含まれています。
root:~# pecl install pdo_oci
WARNING: "pear/PDO_OCI" is deprecated in favor of "channel://http://www.php.net/pdo_oci/ext/pdo_oci"
pear/PDO_OCI requires PHP extension "pdo" (version >= 1.0)
No valid packages found
install failed
しかたがないのでソースからインストールします。config.m4 が 64bit に対応していないので、そのままではエラーになりました。パッチを pdo_oci_config_m4.patch に置きましたのでお試しください。
(追記)インストールして使ってみたら、いきなり ORACLE側がSJISの場合、UTF-8で取り出すと文字列が切れる というバグにぶち当たってしまいました。使えねぇ…。と思っていたらパッチを書いてくれた人を発見。これをいただいて、pdo_oci_statement_c.patchとして置いてあります。
(2012.10.16) このパッチでも元の SJIS データに半角カナが含まれると切れてしまうことがあることが判明。バッファ長を 1.5 倍から 3 倍取るように変更。上記パッチに反映済みです。
root:~# cd /tmp root:~# rm -rf PDO_OCI* root:~# wget http://pecl.php.net/get/PDO_OCI root:~# tar xzf PDO_OCI root:~# cd PDO_OCI-1.0 root:~# patch < /tmp/pdo_oci_config_m4.patch root:~# patch < /tmp/pdo_oci_statement_c.patch root:~# phpize root:~# ./configure \ --prefix=/usr \ --exec-prefix=/usr \ --with-php-config=php-config \ --with-pdo-oci=instantclient,/usr,11.2 root:~# make root:~# make install root:~# cat > /etc/php.d/pdo_oci.ini <<__ ; Enable oci extension module extension=pdo_oci.so __
これで pdo_oci が使えるようになりました。
root:~# php -m|grep -i pdo_oci
PDO_OCI
oracle-instantclient11.2-sqlplus パッケージに含まれている SQL*Plus は Oracle に対して手軽に SQL を発行するための CLI ツールですが、GNU Readline をサポートしておらず、コマンドラインヒストリ(*3)が使えないという今時ありえない時代遅れっぷりです。
(*3)…たとえば↑を押すと直前に実行したコマンドラインが表示され、編集可能状態になる機能。
このような場合、rlwrap(ReadLine Wrapper) というツールをインストールすると、このような Readline 未サポートのアプリケーションでもコマンドヒストリを使えるようになります。せっかくなので入れておきましょう。これは標準の配布物にはないので EPEL(Extra Packages for Enterprise Linux) からインストールしました。
root:~# wget http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel-release-6-7.noarch.rpm root:~# rpm -Uvh epel-release-6-7.noarch.rpm
EPELは非公式リポジトリなので、普段は無効にしておくのが無難かもしれません。無効にするにはすべて enabled=0 になるように以下のファイルをエディタで修正しておきます。
root:~# grep ^enabled /etc/yum.repos.d/epel.repo
enabled=0
enabled=0
enabled=0
新たにパッケージを導入する際、一時的にリポジトリを有効にするには yum に --enablerepo=epel オプションをつけます。
root:~# yum --enablerepo=epel install rlwrap
rlwrap の使い方は簡単です。単にコマンドの前に rlwrap と入れるだけです。
hotta:~$ rlwrap sqlplus64 USER/PASS@HOST/DB SQL*Plus: Release 11.2.0.3.0 Production on Thu Sep 20 16:56:57 2012 Copyright (c) 1982, 2011, Oracle. All rights reserved. Connected to: Oracle Database 10g Release 10.2.0.3.0 - Production SQL> tekitou; SP2-0042: unknown command "tekitou" - rest of line ignored. SQL> (ここで↑キーを押すと) SQL> tekitou; (←これが表示されて修正/実行可能なる) SQL> quit Disconnected from Oracle Database 10g Release 10.2.0.3.0 - Production