Oracle Instant Client を使って PHP をコンパイル

2005-1-5 13:01
このエントリーをはてなブックマークに追加

PHP--with-oci8 オプションを使って configure することで、Oracle のデータベース接続関数を使えるようになります。ところが、--with-oci8 オプションを使ってビルドするためには、Oracle Client がインストールされていなければなりません。Linux に Oracle Client を入れれば良いのですが、OracleInstaller が X Window 必須ですし、インストール用ユーザを作ったりなど、結構手間がかかります。

前回、Oracle Instant Client をインストールする記事を書きましたが、PHP からこれを利用してみます。今回使用したのも RHEL 互換の WhiteBox Linux 3 です。データベースサーバは Windows 2000 Server + Oracle 8i (8.1.7.4) です。

PHP の SRPM をダウンロード

WhiteBox Linux など、Red Hat 系のディストリビューションでは、PHP をソースからコンパイルするよりも、RPM を作った方があとあとの管理が楽です。そこで、ソースRPM (SRPM) から、 Oracle 対応パッケージを作成します。SRPM は kddilab の FTP サイトなどから入手できますし、Red Hat Enterprise Linux のものが使えます。

  $ wget ftp://ftp.kddlabs.co.jp/pub/Linux/packages/whitebox/3.0/en/updates/SRPMS/php-4.3.2-19.ent.src.rpm

SRPM を次のコマンドでインストールすると、/usr/src/redhat/ の下に spec ファイルやソース、パッチが展開されます。

  $ rpm -ivh php-4.3.2-19.ent.src.rpm

specファイの変更

/usr/src/redhat/SPECS ディレクトリに php.spec ファイルがあります。このファイルを編集し、configure オプションに –with-oci8 が含まれるように変更します。

コンパイル手順

コンパイル手順は次の通りです。

  $ rpmbuild -ba php.spec

ただし、ただ再構築するだけでは面白くないので、CPU (今回使用したマシンは Celeron 1.2GHz) にあわせて、最適化オプションを付けました。あまり変わらないとは思いますが。

  $ rpmbuild -ba --target=i686 php.spec

実際に構築を開始すると、依存するライブラリが見つからないというエラーが出ることがあります。たとえば mysql-devel や imap-devel、unixODBC-devel などです。MySQL を利用しなくても RPM の構築には必要ですので、yum install コマンドなどで必要なパッケージをインストールしておきます。また、コンパイルエラーにはなりませんが、PHP の構築時には sendmail、libtool、flex のパッケージがインストールされていないと、一部の関数が使えなくなってしまうなどの弊害があります。これらのパッケージもインストールしておきましょう。

註)php-4.3.2-19.ent.src.rpm からは libtool が BuildRequires に加わっています。

コンパイルエラー

ただし、PHP の --with-oci8 をつけて再構築しただけでは、うまくいきません。Oracle Client と Oracle Instant Client では、ライブラリの位置などが異なるようです。しかし、パッチが公開されていました。このパッチを使った場合は、--with-oci8 ではなく、--with-oci8-instant-client オプションを指定することで、Oracle Instant Client を利用してビルドできます。

Makefile のパッチを RPM に取り込み、再構築してみました。(再構築したパッケージは別途公開する予定です。)すると今度は次のようなエラーが出ました。

  usr/src/redhat/BUILD/php-4.3.2/ext/oci8/oci8.c:5115: `dword' undeclared (first use in this function)
  /usr/src/redhat/BUILD/php-4.3.2/ext/oci8/oci8.c:5115: syntax error before ')' token

ググったところ、Oracle10g の対応のためには、dword によるキャストを dvoid に変更すべきと言うことがわかりました。このパッチを作成し、再度 RPM を構築するとうまくいきました。/usr/src/redhat/RPMS/i686 に php-oci8 パッケージが構築されていれば成功です。

RPM が作成されましたが、インストールしようとすると残念ながら次のようなエラーが出てしまいます。

  # rpm -ivh php-oci8-4.3.2-19.ent.1.i686.rpm
    エラー: Failed dependencies:
        libclntsh.so.10.1 is needed by php-oci8-4.3.2-19.ent.1

libclntsh.so.10.1 ファイルは、/usr/lib/oracle/10.1.0.3/client/lib/ に存在しているのですが、認識されていないようです。そこで、/etc/ld.so.conf の末尾にこのパスを追加し、ldconfig -v としてみましたが、やはり結果は変わりませんでした。仕方ないので、--nodeps オプションを付けて強制的にインストールしました。

  # rpm -ivh --nodeps php-oci8-4.3.2-19.ent.1.i686.rpm

PHP の RPM をインストールしたら、Apache を再起動します。

  # service httpd restart

PHP での設定

次のような簡単な処理を書いて Oracle データベースに接続できるか確認してみます。

<?php
  $dbh = OCILogon( "scott", "tiger", "dbserver:1521/dbname" );
  if ($dbh == NULL) {
    print "DB Connection Error!!";
  } else {
    $sql = "SELECT table_name FROM all_tables";
    $stmt = OCIParse($dbh, $sql);
    if (!$stmt) {
      print "DB Search Error!!";
    } else {
      OCIExecute($stmt);
      $rows = OCIFetchstatement($stmt, $results);
      if ($rows > 0) {
        for ($i = 0; $i < $rows; $i++) {
          print $results["TABLE_NAME"][$i] . "<br>";
        }
      }   
    }
    OCIFreeStatement($stmt);
    OCILogoff($dbh);
  }
?>

OCILogon 関数の引数は環境に合わせて変更して下さい。うまく行けばテーブル名の一覧がずらずらと表示されるはずです。

文字化けの回避

接続はできましたが、いざ日本語のデータを検索してみると、すべて ???? というように文字化けしてしまいました。これは Oracle データベースが SJIS で、クライアント側の文字コード設定が EUC-JP なために起こります。
SQL*Plus のときは環境変数で NLS_LANG=JAPANESE_JAPAN.JA16EUC を指定しましたが、同様の環境変数の設定を Apache が読み込めるように設定する必要があります。Red Hat 系のディストリビューションでは、/etc/sysconfig/httpd に設定を書くのがお約束です。(/etc/init.d/httpd を変更してはいけません。)

   # /etc/sysconfig/httpd
   export NLS_LANG=JAPANESE_JAPAN.JA16EUC

Apache(httpd) を再起動すると文字化けは無くなりました。これで PHP + Oracle Instant Client で使えるようになりました。

2件のコメント

  1. (thumbnail)

    Re: Oracle Instant Client を使って PHP をコンパイル

    Oracle Instant Client を使って PHP をコンパイルより
    YE┐ びよーん ┌- -S!!
    `;??ε? ヽ–く   。    。 °
    RealVNC 4.0″ …

    トラックバック by [牛] うしぶろぐ2005-01-15 11:31

  2. (thumbnail)

    続・Oracle Instant Client を使って PHP をコンパイル

    以前、Oracle Instant Client を使って PHP をコンパイルという記事を書きました。これは、Red Hat Enterprise Linux (正確にはクローンの White Box でしたが)にて、PHP の Oracle 関数を利用できるように再構築する方法を書いたものです。 当時のバージョンでは、Ora…

    トラックバック by 津田ふみかの日記2005-05-6 20:39

現在、コメントフォームは閉鎖中です。

23 queries. HTML convert time: 0.315 sec. Powered by WordPress. Valid XHTML
Copyright © 2003-2013 @ futuremix.org ログイン