PHP Conference Japan 2024

oci_pconnect

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

oci_pconnect使用持久连接连接到Oracle数据库

描述

oci_pconnect(
    string $username,
    string $password,
    ?string $connection_string = null,
    string $encoding = "",
    int $session_mode = OCI_DEFAULT
): resource|false

创建到Oracle服务器的持久连接并登录。

持久连接在请求之间被缓存并重复使用,从而减少每次页面加载的开销;一个典型的PHP应用程序将针对每个Apache子进程(或PHP FPM进程)对Oracle服务器打开一个持久连接。有关更多信息,请参见OCI8连接处理和连接池部分。

参数

用户名

Oracle用户名。

密码

username的密码。

连接字符串

包含要连接的Oracle实例。它可以是» Easy Connect字符串,或tnsnames.ora文件中的连接名,或本地Oracle实例的名称。

如果未指定或为null,PHP将使用环境变量,例如TWO_TASK(在Linux上)或LOCAL(在Windows上)和ORACLE_SID来确定要连接的Oracle实例

要使用Easy Connect命名方法,PHP必须与Oracle 10g或更高版本的客户端库链接。Oracle 10g的Easy Connect字符串格式为:[//]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。确保Web守护进程具有对该文件的读取访问权限。

编码

确定Oracle客户端库使用的字符集。字符集不需要与数据库使用的字符集匹配。如果不匹配,Oracle将尽最大努力将数据转换为数据库字符集以及从数据库字符集转换。根据字符集的不同,这可能无法提供可用的结果。转换还会增加一些时间开销。

如果未指定,Oracle客户端库将从NLS_LANG环境变量确定字符集。

传递此参数可以减少连接所需的时间。

会话模式

此参数从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使用外部或操作系统身份验证,这必须在数据库中进行配置。OCI_CRED_EXT标志只能与用户名“/”和空密码一起使用。oci8.privileged_connect可以是OnOff

OCI_CRED_EXT可以与OCI_SYSOPEROCI_SYSDBA模式组合使用。

出于安全原因,Windows不支持OCI_CRED_EXT

返回值

返回连接标识符或发生错误时返回false

示例

示例 #1 使用Easy Connect语法的基本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:未登录”警告。即使我使用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通过将其放在/etc/init.d/httpd文件中来获取TNS_ADMIN环境变量
TNS_ADMIN=/usr/lib/oracle/11.2/client64/network/admin
export PATH TNS_ADMIN

这可以通过<?php echo system('env'); ?>在PHP中进行调试,并通过验证TNS_ADMIN是否存在来进行。

2. 确保使用tnsnames.ora文件开头的名称 - 不是SID(理想情况下它们应该匹配。但是,如果开头的名称是XXXX.world,则pconnect将期望这个 - 而不是SID)
To Top