これらの関数は Oracle コールインターフェース (OCI) を使用した Oracle 10, Oracle 9, Oracle 8, そして Oracle 7 データベースへのアクセスを可能にします。 これらは PHP 変数の Oracle プレースホルダへのバインドをサポートし、 LOB、FILE、ROWID を完全にサポートしており、 ユーザー定義の変数が使用可能です。
この拡張を使用するために Oracle クライアントライブラリが必要になります。 Windows ユーザは php_oci8.dll を使用するために 少なくともバージョン 10 以降のライブラリが必要になるでしょう。
注意: この拡張モジュールは、Oracle 8 のクライアントライブラリをサポートしません。 とはいえ、バージョン 9 以降のクライアントライブラリが Oracle 8 サーバへの接続をサポートする限りは Oracle 8 サーバに接続することが可能です。
要求される全てのファイルをインストールする最も簡便な方法は、 Oracle Instant Client を使用することです。これは » http://www.oracle.com/technology/tech/oci/instantclient/instantclient.html から取得可能です。 OCI8 モジュールを動作させるには、Oracle Instant Client の 「基本 (basic)」バージョンを導入するだけで十分です。 Instant Client は ORACLE_SID もしくは ORACLE_HOME 環境変数を設定する必要がありませんが、LD_LIBRARY_PATH と NLS_LANG を設定する必要があります。
この拡張モジュールを使用する前に Web デーモンのユーザでもある Oracle ユーザに対する Oracle 用環境変数が正しく設定されていることを 確認してください。これらの変数は Web サーバを起動する 前に 設定されていなければなりません。 設定されている必要がある変数を以下に示します。
Web サーバーのユーザ用に環境変数を設定した後、Web サーバーのユーザ (nobody, www) をグループ oracle に追加してください。
注意: Web サーバが起動しないか、起動時にクラッシュする場合 Apache が pthread ライブラリにリンクされているかどうか 次のように確認してください。
# ldd /www/apache/bin/httpd libpthread.so.0 => /lib/libpthread.so.0 (0x4001c000) libm.so.6 => /lib/libm.so.6 (0x4002f000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x4004c000) libdl.so.2 => /lib/libdl.so.2 (0x4007a000) libc.so.6 => /lib/libc.so.6 (0x4007e000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
libpthread がこの一覧にない場合、Apache を再インストールする必要があります。
# cd /usr/src/apache_1.3.xx # make clean # LIBS=-lpthread ./config.status # make # make install
UnixWare のようないくつかのシステムでは、libpthread の代わりに libthread が使用されています。その場合、PHP と Apache は、 EXTRA_LIBS=-lthread を configure に指定する必要があります。
php.ini の設定により動作が変化します。
名称 | デフォルト | 変更可否 | 変更履歴 |
---|---|---|---|
oci8.privileged_connect | "0" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
oci8.max_persistent | "-1" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
oci8.persistent_timeout | "-1" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
oci8.ping_interval | "60" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
oci8.statement_cache_size | "20" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
oci8.default_prefetch | "10" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
oci8.old_oci_close_semantics | "0" | PHP_INI_SYSTEM | PHP 5.1.2 以降で使用可能 |
以下に設定ディレクティブに関する 簡単な説明を示します。
このオプションは外部の信用 (OCI_SYSOPER, OCI_SYSDBA) を利用して権限付きの接続を有効にします。
プロセスあたりの永続的な OCI8 接続の最大値を指定します。 このオプションを -1 に設定することは、制限なしを意味します。
与えられたプロセスがアイドル状態の永続的接続を維持する最大時間 (秒単位) を指定します。 このオプションを -1 に設定することは、 アイドル状態の永続的接続は永久に維持されることを意味します。
oci_pconnect() の間、ping を発行するまでに経過させる時間 (秒単位) を指定します。 0 に設定した場合、永続的接続は再利用される度に ping を発行します。 ping を完全に無効にするためには、このオプションを -1 に設定します。
注意: ping を無効にすることで oci_pconnect() は最高の効率で処理をコールしますが、ネットワークが分断された場合や PHP が接続した後に Oracle サーバがダウンし、 その後に実行されるスクリプト中において PHP が接続の失敗を検知しなくなります。 詳細な情報は oci_pconnect() を参照ください。
このオプションはステートメントキャッシュを有効にします。 また、キャッシュするステートメントの数を指定します。 ステートメントキャッシュを無効にする場合、このオプションを 0 に設定してください。
注意: より大きなキャッシュは、メモリ使用量の増加と引き替えに パフォーマンスの改善をもたらします。
このオプションはステートメントのプリフェッチを有効にし、 ステートメントの実行後自動的にフェッチされるデフォルトの行数を 設定します。
注意: より大きなプリフェッチは、メモリ使用量の増加と引き替えに パフォーマンスの改善をもたらします。
このオプションは oci_close() の動作を制御します。有効にすると、oci_close() は何も行いません。接続はスクリプトの終了まで閉じられません。 これは後方互換性のためのみに存在しています。 この設定を有効にする必要があると判明した場合、 このオプションを有効にする代わりに、 oci_close() をアプリケーションから削除することが 強く推奨されます。
以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。
Example#1 基本的なクエリ
<?php
$conn = oci_connect('hr', 'hr', 'orcl');
if (!$conn) {
$e = oci_error();
print htmlentities($e['message']);
exit;
}
$query = 'SELECT * FROM DEPARTMENTS';
$stid = oci_parse($conn, $query);
if (!$stid) {
$e = oci_error($conn);
print htmlentities($e['message']);
exit;
}
$r = oci_execute($stid, OCI_DEFAULT);
if (!$r) {
$e = oci_error($stid);
echo htmlentities($e['message']);
exit;
}
print '<table border="1">';
while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS)) {
print '<tr>';
foreach ($row as $item) {
print '<td>'.($item?htmlentities($item):' ').'</td>';
}
print '</tr>';
}
print '</table>';
oci_close($conn);
?>
Example#2 バインド変数を用いた挿入
<?php
// 実行前に表を作成する
// CREATE TABLE MYTABLE (mid NUMBER, myd VARCHAR2(20));
$conn = oci_connect('scott', 'tiger', 'orcl');
$query = 'INSERT INTO MYTABLE VALUES(:myid, :mydata)';
$stid = oci_parse($conn, $query);
$id = 60;
$data = 'Some data';
oci_bind_by_name($stid, ':myid', $id);
oci_bind_by_name($stid, ':mydata', $data);
$r = oci_execute($stid);
if ($r)
print "One row inserted";
oci_close($conn);
?>
Example#3 CLOB カラムにデータを挿入する
<?php
// 実行前に表を作成する
// CREATE TABLE MYTABLE (mykey NUMBER, myclob CLOB);
$conn = oci_connect('scott', 'tiger', 'orcl');
$mykey = 12343; // この例で用いる任意のキー
$sql = "INSERT INTO mytable (mykey, myclob)
VALUES (:mykey, EMPTY_CLOB())
RETURNING myclob INTO :myclob";
$stid = oci_parse($conn, $sql);
$clob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stid, ":mykey", $mykey, 5);
oci_bind_by_name($stid, ":myclob", $clob, -1, OCI_B_CLOB);
oci_execute($stid, OCI_DEFAULT);
$clob->save("A very long string");
oci_commit($conn);
// CLOB データをフェッチする
$query = 'SELECT myclob FROM mytable WHERE mykey = :mykey';
$stid = oci_parse ($conn, $query);
oci_bind_by_name($stid, ":mykey", $mykey, 5);
oci_execute($stid, OCI_DEFAULT);
print '<table border="1">';
while ($row = oci_fetch_array($stid, OCI_ASSOC)) {
$result = $row['MYCLOB']->load();
print '<tr><td>'.$result.'</td></tr>';
}
print '</table>';
?>
コマンドラインで実行するのと同様な手法により、ストアドプロシージャ に簡単にアクセス可能です。
Example#4 ストアドプロシージャの使用法
<?php
// by webmaster at remoterealty dot com
$sth = oci_parse($dbh, "begin sp_newaddress( :address_id, '$firstname',
'$lastname', '$company', '$address1', '$address2', '$city', '$state',
'$postalcode', '$country', :error_code );end;");
// この命令は、:address_id を入出力変数、:error_code を出力変数として
// ストアドプロシージャ sp_newaddress をコールします。
// 続いて、以下のようにバインドを実行します。
oci_bind_by_name($sth, ":address_id", $addr_id, 10);
oci_bind_by_name($sth, ":error_code", $errorcode, 10);
oci_execute($sth);
?>
oci8 拡張モジュールは Oracle に接続するための 3 つの異なる関数を提供しています。 アプリケーションに最適な関数を使用するのはあなた次第です。 また、このセクションにある情報は、 インフォームド・チョイス (十分な説明を受けよく考えた上での選択) を行う助けになることを目的としています。
Oracle サーバへの接続は、完了まで要する時間という点から見ると、 かなりコストのかかる操作です。oci_pconnect() 関数は、 異なるスクリプトリクエスト間で接続の再利用が可能な 持続的キャッシュを使用します。 これは、PHP プロセス (もしくは Apache の子プロセス) 毎の接続に関するオーバーヘッドを一度のみ負うということを意味しています。
もしアプリケーションが信用された異なる Web ユーザー毎に Oracle に接続する場合、oci_pconnect() による持続的キャッシュは、 同時ユーザー数の増加と共に有効ではなくなるでしょう。 これは、多くのアイドル状態の接続が維持されることが原因で、 Oracle サーバ全体のパフォーマンスに不利な影響を与え始めるためです。 もしアプリケーションがこの方法で構成されている場合、 oci8.max_persistent や oci8.persistent_timeout (持続的接続のキャッシュサイズや生存期間の制御が可能になります) を使用してアプリケーションをチューニングする、もしくは代わりに oci_connect() を使用することが推奨されます。
oci_connect() と oci_pconnect() の両者とも接続キャッシュを使用します。もし、同一パラメータと共に oci_connect() を複数回コールする場合、 2 番目以降は既存の接続ハンドルを返します。oci_connect() によって使用されるキャッシュは、スクリプト実行終了時、 もしくは明示的に接続ハンドルを閉じた時にクリアされます。 oci_pconnect() も同様の動作をしますが、 キャッシュは独立して維持され、リクエスト間で残存します。
このキャッシュ機能は忘れてはならないほど重要です。 それは、2 つのハンドルがトランザクション的に独立していない (実際には同じ接続なので、どのような種類の独立もありません) ためです。もしアプリケーションが 2 つの別々でトランザクション的に独立した接続を必要とする場合、 oci_new_connect() を使用すべきです。
oci_new_connect() は、他の既存の接続が存在したとしても 常に Oracle サーバへの新規接続を生成します。 特にアプリケーションの最も負荷が高い部分など、 高トラフィックな Web アプリケーションに対しては oci_new_connect() の使用を避けてください。
型 | マッピング |
---|---|
SQLT_NTY | oci_new_collection() によって生成されたような PHP のコレクションオブジェクトからネイティブのコレクション型に マップします |
SQLT_BFILEE | oci_new_descriptor() によって生成されたような PHP のディスクリプタオブジェクトからネイティブのディスクリプタ型に マップします |
SQLT_CFILEE | oci_new_descriptor() によって生成されたような PHP のディスクリプタオブジェクトからネイティブのディスクリプタ型に マップします |
SQLT_CLOB | oci_new_descriptor() によって生成されたような PHP のディスクリプタオブジェクトからネイティブのディスクリプタ型に マップします |
SQLT_BLOB | oci_new_descriptor() によって生成されたような PHP のディスクリプタオブジェクトからネイティブのディスクリプタ型に マップします |
SQLT_RDD | oci_new_descriptor() によって生成されたような PHP のディスクリプタオブジェクトからネイティブのディスクリプタ型に マップします |
SQLT_NUM | PHP パラメータを 'C' の long 型に変換し、 その値をバインドします |
SQLT_RSET | oci_parse() によって生成されたもしくは他の OCI クエリから処理されたような PHP のステートメントハンドルからネイティブのステートメントハンドルに マップします |
SQLT_CHR や他の型 | PHP パラメータを文字列型に変換し、その文字列をバインドします |
型 | マッピング |
---|---|
SQLT_RSET | カーソルを表す OCI ステートメントリソースを生成します |
SQLT_RDD | ROWID オブジェクトを生成します |
SQLT_BLOB | LOB オブジェクトを生成します |
SQLT_CLOB | LOB オブジェクトを生成します |
SQLT_BFILE | LOB オブジェクトを生成します |
SQLT_LNG | SQLT_CHR としてバインドし、文字列として返します |
SQLT_LBI | SQLT_BIN としてバインドし、文字列として返します |
Any other type | SQLT_CHR としてバインドし、文字列として返します |