PHP Conference Japan 2024

oci_pconnect

(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)

oci_pconnect使用永久連線連線至 Oracle 資料庫

說明

oci_pconnect(
    字串 $username,
    字串 $password,
    ?字串 $connection_string = null,
    字串 $encoding = "",
    整數 $session_mode = OCI_DEFAULT
): 資源|false

建立與 Oracle 伺服器的永久連線並登入。

永久連線會在請求之間被快取並重複使用,從而減少每個頁面載入的負擔;典型的 PHP 應用程式每個 Apache 子程序(或 PHP FPM 程序)都會對 Oracle 伺服器開啟一個永久連線。有關詳細資訊,請參閱OCI8 連線處理與連線池章節。

參數

username

Oracle 使用者名稱。

password

username 的密碼。

connection_string

包含要連線的 Oracle 實例。它可以是 » 簡易連線字串tnsnames.ora 檔案中的連線名稱,或是本機 Oracle 實例的名稱。

如果未指定或為 null,PHP 會使用環境變數(例如 Linux 上的 TWO_TASK 或 Windows 上的 LOCAL)和 ORACLE_SID 來判斷要連線的 Oracle 實例

若要使用簡易連線命名方法,PHP 必須連結 Oracle 10g 或更高版本的用戶端程式庫。Oracle 10g 的簡易連線字串格式如下:[//]host_name[:port][/service_name]。從 Oracle 11g 開始,語法為:[//]host_name[:port][/service_name][:server_type][/instance_name]。Oracle 19c 引入了更多選項,包括逾時和保持連線設定。請參閱 Oracle 文件。服務名稱可以透過在資料庫伺服器機器上執行 Oracle 公用程式 lsnrctl status 來找到。

tnsnames.ora 檔案可以在 Oracle Net 搜尋路徑中,包括 /your/path/to/instantclient/network/admin$ORACLE_HOME/network/admin/etc。或者設定 TNS_ADMIN,以便讀取 $TNS_ADMIN/tnsnames.ora。請確保網頁伺服器精靈對該檔案具有讀取權限。

encoding

決定 Oracle 用戶端程式庫使用的字元集。字元集不需要與資料庫使用的字元集相同。如果不同,Oracle 會盡力將資料轉換為資料庫字元集以及從資料庫字元集轉換。根據字元集的不同,這可能不會產生可用的結果。轉換也會增加一些時間負擔。

如果未指定,Oracle 用戶端程式庫會從 NLS_LANG 環境變數中判斷字元集。

傳遞此參數可以減少連線所需的時間。

session_mode

此參數自 PHP 5 版本(PECL OCI8 1.1)起可用,並接受下列值:OCI_DEFAULTOCI_SYSOPEROCI_SYSDBA。如果指定了 OCI_SYSOPEROCI_SYSDBA,此函式將嘗試使用外部憑證建立具有權限的連線。具有權限的連線預設為停用。若要啟用它們,您需要將 oci8.privileged_connect 設定為 On

PHP 5.3 (PECL OCI8 1.3.4) 引入了 OCI_CRED_EXT 模式值。這會告訴 Oracle 使用外部或 OS 驗證,這必須在資料庫中設定。OCI_CRED_EXT 旗標只能與使用者名稱 "/" 和空白密碼一起使用。oci8.privileged_connect 可以是 OnOff

OCI_CRED_EXT 可以與 OCI_SYSOPEROCI_SYSDBA 模式組合使用。

由於安全性考量,Windows 上不支援 OCI_CRED_EXT

傳回值

如果成功,返回連線識別字;失敗則返回 false

範例

範例 #1 基本 oci_pconnect() 範例,使用簡易連線語法

<?php

// 連線至 "localhost" 機器上的 XE 服務(即資料庫)
$conn = oci_pconnect('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 employees');
oci_execute($stid);

echo
"<table border='1'>\n";
while (
$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo
"<tr>\n";
foreach (
$row as $item) {
echo
" <td>" . ($item !== null ? htmlentities($item, ENT_QUOTES) : "&nbsp;") . "</td>\n";
}
echo
"</tr>\n";
}
echo
"</table>\n";

?>

有關參數使用的更多範例,請參閱 oci_connect()

注意

注意 每個 PHP 程序中永久 Oracle 連線的生命週期和最大數量可以透過設定下列配置值來調整:oci8.persistent_timeoutoci8.ping_intervaloci8.max_persistent

參見

新增註解

使用者提供的註解 2 註解

2
php at jaggard dot org dot uk
16 年前
[編輯註記:OCI8 1.3 不應發生此使用者評論中描述的問題。首次使用此類連線將會返回一個 Oracle 錯誤,這將觸發 PHP 中的清理。後續的持續連線呼叫將會成功。對於高可用性,您可以考慮在您的腳本中進行連續的 oci_pconnect 呼叫。]

如果您使用 oci_pconnect 連線,而該連線已將您登出但仍然有效,似乎沒有辦法重新使用該連線。下次我嘗試 oci_pconnect 然後執行 oci_execute 操作時,我會收到「ORA-01012: not logged on」警告。即使我使用 oci_close 關閉連線,這個問題仍然存在。我最終得到了以下(相當惱人)的程式碼。

<?php
function getOracleConnection()
{
if (!
function_exists('oci_pconnect'))
return
false;
$toReturn = oci_pconnect('user', 'pass', 'db');
if (
$testRes = @oci_parse($toReturn, 'SELECT Count(group_type_code) FROM pvo.group_type'))
if (@
oci_execute($testRes))
if (@
oci_fetch_array($testRes))
return
$toReturn;
oci_close($toReturn);
if (!
function_exists('oci_connect'))
return
false;
$toReturn = oci_connect('user', 'pass', 'db');
if (
$testRes = @oci_parse($toReturn, 'SELECT Count(group_type_code) FROM pvo.group_type'))
if (@
oci_execute($testRes))
if (@
oci_fetch_array($testRes))
return
$toReturn;
oci_close($toReturn);
if (!
function_exists('oci_new_connect'))
return
false;
$toReturn = oci_new_connect('user', 'pass', 'db');
if (
$testRes = @oci_parse($toReturn, 'SELECT Count(group_type_code) FROM pvo.group_type'))
if (@
oci_execute($testRes))
if (@
oci_fetch_array($testRes))
return
$toReturn;
oci_close($toReturn);
return
false;
}
?>
0
gotankersley at NOSPAM dot com
12 年前
安裝在 CentOS 6.2 上,並且在讓它識別 tnsnames.ora 時遇到很多麻煩。我的解決方法是

1. 確保 apache 通過將 TNS_ADMIN 環境變數放入 /etc/init.d/httpd 檔案中來取得它
TNS_ADMIN=/usr/lib/oracle/11.2/client64/network/admin
export PATH TNS_ADMIN

這可以在 PHP 中通過 <?php echo system('env'); ?> 進行除錯,並驗證 TNS_ADMIN 是否存在。

2. 確保使用 tnsnames.ora 檔案開頭的名稱 - 而不是 SID(儘管理想情況下它們應該匹配)。但是,如果開頭的名稱是 XXXX.world,那麼 pconnect 將會期望這個名稱 - 而不是 SID)
To Top