PHP Australia Conference 2015

oci_close

(PHP 5, PECL OCI8 >= 1.1.0)

oci_closeOracleとの接続を閉じる

説明

bool oci_close ( resource $connection )

接続 connection を閉じます。 他のいかなるリソースも利用しない、なおかつ oci_connect() または oci_new_connect() で作成された場合、 基礎となるデータベース接続が閉じられます。

もはや不要となった接続を閉じることを推奨します。 なぜなら、これにより他のユーザーがデータベースリソースを利用できるようになるからです。

パラメータ

connection

oci_connect()oci_pconnect() あるいは oci_new_connect() が返す Oracle 接続 ID。

返り値

成功した場合に TRUE を、失敗した場合に FALSE を返します。

例1 接続を閉じる

基礎となるデータベース接続がきちんと終了され、データベースリソースが解放されることを確実にするために、 接続に関連したリソースは閉じられるべきです。

<?php

$conn 
oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid oci_parse($conn'SELECT * FROM departments');
$r oci_execute($stid);
oci_fetch_all($stid$res);
var_dump($res);

// 接続を閉じるときにステートメント識別子を解放します
oci_free_statement($stid);
oci_close($conn);

?>

例2 参照の全てが閉じられるまでデータベース接続は閉じられません

基礎となるデータベースへの接続が閉じられる前に 接続の内部的な参照回数識別子はゼロで無ければいけません

<?php

$conn 
oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid oci_parse($conn'SELECT * FROM departments');  // これは $conn の参照回数を増やします
oci_execute($stid);
oci_fetch_all($stid$res);
var_dump($res);

oci_close($conn);

// $conn はもはやスクリプトで使用できませんが、基礎となるデータベース接続は
// $stid が解放されるまで開かれたまま保たれます。
var_dump($conn);  // NULL を出力 

// PHP が活動していない間にターミナルウィンドウで Oracle の V$SESSION ビューを
// 参照すると、データベースユーザーがまだ接続されていると表示します。
sleep(10);

// $stid が解放されると、データベース接続は物理的に閉じられます。
oci_free_statement($stid);  

// PHP が活動していない間にターミナルウィンドウで Oracle の V$SESSION ビューを
// 参照すると、データベースユーザーが切断されたと表示します。
sleep(10);

?>

例3 一回以上開かれた接続を閉じる

データベースクレデンシャルが再利用されるときは、基礎となるデータベース接続が閉じられる前に、 両方の接続がともに閉じられていなければいけません。

<?php

$conn1 
oci_connect('hr''welcome''localhost/XE');

// 同じ基礎となるデータベース接続を再利用するクレデンシャルを使用すると、
// $conn1 上でなされたコミットされていない変更は全て、 $conn2 で認識できます。
$conn2 oci_connect('hr''welcome''localhost/XE');

// PHP が活動していない間にターミナルウィンドウで Oracle の V$SESSION ビューを
// 参照すると、データベースユーザーが一つだけ接続されたと表示します。
sleep(10);

oci_close($conn1); // 基礎となるデータベース接続を閉じません。
var_dump($conn1);  // 変数 $conn1 がもはや利用できないので NULL を出力します
var_dump($conn2);  // $conn2 はまだ有効な接続リソースと表示されます。

?>

例4 変数がスコープから外れると接続が閉じられます

接続を参照する変数の全てがスコープを外れてPHPにより解放されると、 (必要に応じて)ロールバックが発生します。 そしてデータベースへの基礎となる接続が閉じられます。

<?php

function myfunc() {
    
$conn oci_connect('hr''hrpwd''localhost/XE');
    if (!
$conn) {
        
$e oci_error();
        
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
    }

    
$stid oci_parse($conn'UPDATE mytab SET id = 100');
    
oci_execute($stidOCI_NO_AUTO_COMMIT);
    return 
"Finished";
}

$r myfunc();
// この時点でロールバックが発生し、基礎となるデータベース接続が閉じられます。

print $r;  // 関数の返り値 "Finished" を表示します

?>

注意

注意:

接続識別子に依存する変数、たとえば oci_parse() により返される ステートメント識別子のような変数は、基礎となるデータベース接続が閉じられる前に 解放されなければいけません。

注意:

PHP 5.1.2 (PECL OCI8 1.1) より前のバージョンでは、oci_close() は実際には何もしませんでした。最近のバージョンでは、きちんと Oracle 接続を閉じます。 この関数の古い動作をさせる場合は oci8.old_oci_close_semantics オプションを使用してください。

注意:

oci_close() 関数は oci_pconnect() で作成された基礎となるデータベース接続を 閉じません。

参考

add a note add a note

User Contributed Notes 2 notes

up
0
Fahd Alwashmi (F-A-W)
2 years ago
please note, you can use oci_close() to close persistent connections opened with oci_pconnect() in PHP ver 5.3 or above.
as stated in here:
http://www.php.net/manual/en/oci8.configuration.php#ini.oci8.persistent-timeout
up
0
yepster at hotmail dot com
12 years ago
For using persistent connections && being able to sleep, I use:

function close_db_locks_on_abort( ) {
    global $conn;
    if( connection_aborted() ) {
        $fp = fopen( "/tmp/shutdown-func.txt", "a" );
        fwrite( $fp, sprintf( "connection aborted on %s\n", date( "d-m-Y H:i:s" ) ) );
        if( $conn ) {
            OCIRollBack( $conn );
            fwrite( $fp, sprintf( "-- DURING CONNECTION! ip=%s, user=%s, page=%s\n", $_SERVER["REMOTE_ADDR"], $_SERVER["PHP_AUTH_USER"], $_SERVER["SCRIPT_FILENAME"] ) );
        }
        fclose( $fp );
    }
}

register_shutdown_function ( "close_db_locks_on_abort" );

This makes sure a rollback is done on a connection when a user hits 'stop', so there will be no locks on table rows.
To Top