要连接到 Oracle,可以使用 PHP 的 oci_connect() 调用:
$c = oci_connect($username, $password, $dbname)每个 oci_connect() 连接均存储在高速缓存中。当同一脚本中出现第二个 oci_connect() 时,将返回前一个高速缓存的连接。脚本完成时将清除该高速缓存。
$c = oci_new_connect($username, $password, $dbname)持久连接在 PHP 脚本结束时不会自动关闭。它们仍保持打开状态,以便在其他脚本中重用:
$c = oci_pconnect($username, $password, $dbname)当打开连接的开销很大时,使用持久连接很有好处。开销是否大取决于应用程序要求以及实现问题(如 web 服务器和数据库是否位于同一主机中)。
oci8.max_persistent:该参数限制高速缓存的持久连接数。达到该限制时,所有 oci_pconnect() 调用均被视为 oci_connect() 调用。将该参数设置为 -1(默认值)表示没有限制。
oci8.persistent_timeout:Apache 进程保持空闲持久连接的时间(以秒为单位)。每当 PHP 脚本完成时,无论脚本是否调用 oci8 函数,都将执行到期检查。将该参数设置为 -1(默认值)表示没有超时。如果连接已过期,oci_pconnect() 将创建一个新连接。
oci8.ping_interval:oci8 在执行 oci_pconnect() 过程中执行 ping 操作之前经过的秒数。如果该参数设置为 0,则 PHP 将在每次调用 oci_pconnect() 时对数据库执行 ping 操作。要禁用 ping,将该值设置为 -1。默认值为 60 秒。如果 ping 确定连接不可用,则将创建一个新连接。
简单连接字符串
完整连接字符串
tnsnames.ora 别名
//hostname:port/service_name对于使用默认端口 1521 的 Oracle 数据库特别版,只需使用“//localhost/XE”。
$c = oci_connect('hr', 'hrpw', '//localhost/XE');必须具有 Oracle 10 g 客户端库才能使用简单连接语法。ZCO 具有相应的 Oracle 库。
$db = MYDB2 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP) (HOST = mymachine.mydomain)(PORT = 1521)) (CONNECT_DATA= (SERVER = DEDICATED) (SERVICE_NAME = MYDB.AU.ORACLE.COM)))'; $c = oci_connect($un, $pw, $db);如果存在疑问,请复制其他 Oracle 工具和用户使用的连接字符串。
# tnsnames.ora MYDB2 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP) (HOST = mymachine.mydomain)(PORT = 1521)) (CONNECT_DATA= (SERVER = DEDICATED) (SERVICE_NAME = MYDB.AU.ORACLE.COM)))在 PHP 中,可以使用以下代码进行连接:
$c = oci_connect($un, $pw, 'MYDB2');PHP 需要能找到 tnsnames.ora 文件来解析别名“MYDB2”。这是一个常见问题。
$ORACLE_HOME/network/admin/tnsnames.ora即
/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/network/admin/tnsnames.ora无论是使用默认位置还是其他位置,Apache 必须能够在启动时找到该目录。通常情况下(包括在 ZCO 中),这通过设置 TNS_ADMIN 环境变量实现。
#!/bin/sh TNS_ADMIN=/usr/local/apache/conf export TNS_ADMIN echo Starting Apache #export > /tmp/envvars /usr/local/apache/bin/apachectl start该示例假设 /usr/local/apache/conf/tnsnames.ora 存在。TNS_ADMIN 指向包含 tnsnames.ora 文件的目录。
oci_close($c);将回滚任何未提交的数据。
$c1 = oci_connect('hr', 'hrpw', '//localhost/XE'); $c2 = oci_connect('hr', 'hrpw', '//localhost/XE'); do_query($c1, 'select user from dual'); oci_close($c1); do_query($c1, 'select user from dual'); do_query($c2, 'select user from dual'); oci_close($c2);在重构 oci8 之前,oci_close() 函数是一个无操作函数。即使在需要的情况下,您也无法显式关闭连接。现在,这种情况发生了变化,但您可以在必要时通过在 php.ini 中设置 oci8.old_oci_close_semantics 来恢复为旧行为。将 oci8.old_oci_close_semantics 设置为 1 可以使 oci_close() 再次成为无操作函数。默认值 0 表示 oci_close() 将关闭连接。
分析 - 准备一个要执行的语句
绑定 - 可以有选择地让您绑定数据值(例如,在 WHERE 子句中)以便提高性能和安全性
定义 - 一个可选步骤,使您可以指定哪些 PHP 变量将保存结果。(不常见?)
执行 - 数据库处理该命令并缓冲结果。
获取 - 从数据库中取回查询结果。Oci8 提供了一些可供选择的获取语句。
$stid = oci_parse($c, 'select * from locations'); oci_execute($stid, OCI_DEFAULT); oci_fetch_all($stid, $res);确保在必要时使用双引号:
$stid = oci_parse($c, "select * from locations where city = 'Sydney'");oci8 包含一些 fetch 函数,PHP oci8 参考手册对其进行了详细说明。
oci_fetch_all():一次性获取所有结果
oci_fetch_array():以您选择的数组形式获取下一行
oci_fetch_assoc():以关联数组的形式获取下一行
oci_fetch_object():以对象形式获取新行
oci_fetch_row():以整数索引的数组形式获取下一行
oci_fetch():与 oci_result()(返回给定字段的结果)一起使用
$stid = oci_parse($c, "select city from locations"); oci_execute($stid, OCI_DEFAULT); while ($res = oci_fetch_row($stid)) { echo $res[0] ."<br>\n"; }某些函数包含可更改其行为的可选参数,例如,oci_fetch_array() 提供了一些选项,用于指定是以关联数组形式还是以数字索引数组形式(或同时以关联数组和数字索引数组形式)返回结果。关联数组使用大写列名命名。
oci8.default_prefetch:当执行每个数据库获取操作时 Oracle 返回的记录数。默认值为 10。调整该设置可以显著提高返回大量行的查询的性能。它每次返回尽可能多的数据,从而最大限度地降低了数据库服务器的“往返”次数。Oracle 将数据高速缓冲在它的客户端缓冲区中,并只向 PHP 提供 PHP 本身请求的行。
oci8.statement_cache_size:支持 OCI 客户端语句高速缓存。默认值为 20 个语句。可以通过将该值设置为 0 来禁用高速缓存。客户端语句高速缓存意味着甚至不需要将语句文本传输给数据库,从而进一步减少了网络通信量和服务器负载。高速缓存是一个纯 Oracle 会话,因此当使用持久连接时,该特性通常很有用。
$s = oci_parse($c1, "create table i1test (col1 number)"); $r = oci_execute($s, OCI_DEFAULT); $s = oci_parse($c1, "insert into i1test values (1)"); $r = oci_execute($s, OCI_DEFAULT);只有一次性的应用程序配置部分才应使用 CREATE TABLE 。某些用户认为应用程序需要创建临时表,而 Oracle 与其他数据库的限制并不相同。
$r = oci_execute($s, OCI_DEFAULT);oci_execute() 的默认模式为 OCI_COMMIT_ON_SUCCESS(其名称显示了它的功能)。而不必要的提交会影响数据库性能,这是因为它将导致不必要的网络通信量以及导致数据库文件 I/O 的浪费。这就是为什么首选 OCI_DEFAULT 的原因。
$s = oci_parse($c, "insert into i2test values ('row 1')"); $r = oci_execute($s); $s = oci_parse($c, "insert into i2test values ('row 2')"); $r = oci_execute($s, OCI_DEFAULT);
$c = oci_connect("hr", "hr", "//localhost/XE"); if (!$c) { $e = oci_error(); // no resource passed var_dump($e); } $stid = oci_parse($c, "select city from locations"); if (!$stid) { $e = oci_error($c); // connection resource passed var_dump($e); } $rc = oci_execute($stid, OCI_DEFAULT); if (!$rc) { $e = oci_error($stid); // statement resource passed var_dump($e); } $rc = oci_fetch_all($stid, $results); if (!$rc) { $e = oci_error($stid); // statement resource passed var_dump($e); }
$stid = oci_parse($c, "select last_name from employees where employee_id = :eidbv"); $myeid = 101; oci_bind_by_name($stid, ":EIDBV", $myeid); oci_execute($stid, OCI_DEFAULT); oci_fetch_all($stid, $res); echo "Last name is:". $res['LAST_NAME'][0] ."\n"; // No need to re-parse $myeid = 102; oci_execute($stid, OCI_DEFAULT); oci_fetch_all($stid, $res); echo "Last name is:". $res['LAST_NAME'][0] ."\n";绑定数据在调用 oci_execute() 时应可以访问。在 sub 函数中使用局部变量可能会导致作用域问题。
在某种情况下,您可能决定不使用绑定变量。当语句包含绑定变量时,优化器不知道您最终要使用的值。如果数据很固定,则您可能要对值进行硬编码。但如果数据是由用户输入,确保对其进行处理。