概要

oci経由でOracleへ接続するPDOオブジェクトをnewしようとすると例外が送出される。

$pdo = new PDO('oci:', '{DATABASE}', '{PASSWORD}') ;
// => SQLSTATE[]: pdo_oci_handle_factory: OCI_INVALID_HANDLE (/usr/local/build/php-5.2.8/ext/pdo_oci/oci_driver.c:578)

環境

  • Apache 2.2.14
  • PHP 5.2.8
  • Oracle Database 10g Express Edition Release 10.2.0.1.0
  • CentOS release 5.4 (Final) (Hosted on Virtual Box at Windows 7 Enterprise)

原因と対処

原因

  • PHPのconfigure optionにoci / oci8が指定されていなかった。
  • Apacheの起動時、Oracleクライアントが動作するのに必要な環境変数が設定されていなかった。

対処1

oci / oci8を有効にするオプションをつけて、PHPを再コンパイルする。

configure(例)

Configure Command => './configure' \
 '--prefix=/usr/local' \
 '--with-apxs2=/usr/local/apache2/bin/apxs' \
 '--with-mysql' \
 '--with-openssl' \
 '--with-zlib' \
 '--with-curl' \
 '--with-ftp' \
 '--with-pdo-mysql' \
 '--with-readline' \
 '--with-config-file-path=/etc' \
 '--with-pdo-oci=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server' \
 '--with-oci8=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server' \
 '--enable-mbstring'

対処2

Apacheの起動スクリプトから、Oracleの環境変数設定スクリプトを呼び出す。

起動スクリプト(例)

  • /etc/init.d/httpd
  • /usr/local/apache2/bin/apachectl

追記するコード(例)

. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh

ポイント

  • 設定 / 運用によるが、起動時にchkconfigから呼ばれるスクリプトと手動で起動 / 停止を行うスクリプトの両方に記入する必要がある。
  • 記入する場所はhttpdのプロセスを起動するcase文の前に。
  • 記入後「apachectl restart」ではダメな場合がある。stop→startしたほうがよい(参考)。
  • Ocale系のパス(/usr/lib/oracle/…)は「$ORACLE_HOME」を展開したもの。環境に合わせて読み替える。

雑感

解決方法のヒントはOracle本家(英語)のWikiと「The Underground PHP and Oracle Manual」という恐ろしい名前のPDFにあった。英語重要。読む力ももちろんだけど「ググるための英語力」も。