PDO_OCI のインストール


(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 ということで同梱されていないようです。

1.PHP のインストール

まずはベースとなる 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

2.Oracle Instant Client のインストール

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

3.PDO_OCI のインストール

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

4.(おまけ)rlwrap のインストール

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

Go previous Go ahead Go up