|
Oracle/PHP 常见问题解答
作者 Frank Naudé
主题
PHP 是什么,它与 Oracle 有什么关系?
PHP 是"PHP 超文本预处理程序 (PHP Hypertext Preprocessor)"的递归首字母缩写。它是一种开放源代码的、解释的、以 HTML 为中心的服务器端脚本语言。PHP 特别适用于 Web 开发,可以被嵌入到 HTML 页中。PHP 类似于 JSP (Java Server Pages) 和 Oracle 的 PSP (PL/SQL Server Pages)。
本常见问题解答说明 PHP 如何与 Oracle 数据库进行交互。它假定读者已经安装了 PHP 并正在运行。要测试 PHP 是否正在运行,可以创建一个简单的 PHP 文档,称为 hello.php:
<html>
<p>If PHP is working, you will see "Hello World" below:<hr>
<?php
echo "Hello world";
phpinfo(); // Print PHP version and config info
?>
</html>
从命令行执行 hello.php (php hello.php) 或从 web 浏览器打开它 (http://localhost/hello.php),查看其输出。如果它没有运行,则没有正确安装 PHP,此常见问题解答将不能帮助您。
注意,Oracle HTTP 服务器 (Apache) 发行版本中没有预装 PHP (mod_php),并且 Oracle 不支持 mod_php 或该语言本身,但是它可以支持包含 mod_php 的配置。(查看此发展方向说明获得详细阐述。)
返回页首
OCI 和 ORA 扩展模块之间有什么不同?
PHP 提供两种可用于连接 Oracle 的扩展模块:
- 正常 Oracle 函数 (ORA);
- Oracle 调用接口函数 (OCI)。
在可能的情况下应该尽量使用 OCI,因为它经过优化,可提供更多选项。例如,ORA 不包含对 CLOB、BLOB、BFILE、ROWID 等的支持。
返回页首
如何配置 PHP 来使用 Oracle?
按照以下步骤执行,准备将 PHP 安装文件连接到 Oracle 数据库:
返回页首
如何连接 Oracle?
使用 OCI 扩展模块:
<?php
if ($c=OCILogon("scott", "tiger", "orcl")) {
echo "Successfully connected to Oracle.\n";
OCILogoff($c);
} else
$err = OCIError();
echo "Oracle Connect Error " .$err[text];
}
?>
使用 ORA 扩展模块:
<?php
if ($c=ora_logon("scott@orcl","tiger")) {
echo "Successfully connected to Oracle.\n";
ora_commitoff($c);
ora_logoff($c);
} else
echo "Oracle Connect Error " . ora_error();
}
?>
注意:您可能希望在连接之前在 PHP 中设置 Oracle 环境。请看此示例:
<?php
PutEnv("ORACLE_SID=ORCL");
PutEnv("ORACLE_HOME=/app/oracle/product/9.2.0");
PutEnv("TNS_ADMIN=/var/opt/oracle");
...
请注意,如果在特定的"页面"或 httpd 服务器会话中使用了相同的 userid/password 组合(多于一次),则 PHP 将共享/重用这些连接。您可以使用 OCINLogon() 函数以确保获得新的会话。使用 OCIPLogon() 函数可进行进行持续的连接。
返回页首
为什么会遇到错误 "Call to undefined function:ora_logon()/ ocilogon()"?
PHP 没有使用正确的扩展模块。试用以下选项编译 PHP:
--with-oracle=/path/to/oracle/home/dir
--with-oci8=/path/to/oracle/home/dir
在 Windows 系统中,您只须在 php.ini 文件中取消以下行的注释:
;extension = php_oci8.dll
;extension = php_oracle.dll
返回页首
如何从 PHP 选择、插入、更新和删除数据?
以下示例演示如何通过 INSERT、UPDATE 和 DELETE 语句选择和处理数据:
<?php
$c=OCILogon("scott", "tiger", "orcl");
if ( !$c ) {
echo "Unable to connect:" . var_dump( OCIError() );
die();
}
// Drop old table...
$s = OCIParse($c, "drop table tab1");
OCIExecute($s, OCI_DEFAULT);
// Create new table...
$s = OCIParse($c, "create table tab1 (col1 number, col2 varchar2(30))");
OCIExecute($s, OCI_DEFAULT);
// Insert data into table...
$s = OCIParse($c, "insert into tab1 values (1, 'Frank')");
OCIExecute($s, OCI_DEFAULT);
// Insert data using bind variables...
$var1 = 2;
$var2 = "Scott";
$s = OCIParse($c, "insert into tab1 values (:bind1, :bind2)");
OCIBindByName($s, ":bind1", $var1);
OCIBindByName($s, ":bind2", $var2);
OCIExecute($s, OCI_DEFAULT);
// Select Data...
$s = OCIParse($c, "select * from tab1");
OCIExecute($s, OCI_DEFAULT);
while (OCIFetch($s)) {
echo "COL1=" . ociresult($s, "COL1") .
", COL2=" . ociresult($s, "COL2") ."\n";
}
// Commit to save changes...
OCICommit($c);
// Logoff from Oracle...
OCILogoff($c);
?>
返回页首
在 PHP 中如何处理数据库事务?
当使用 OCI 扩展模块时,必须显式提交或回滚数据库事务。为此提供了 OCICommit() 和 OCIRollback() 函数。
ORA 扩展模块支持自动提交模式。使用 ORA_CommitOn() 和 ORA_CommitOff() 函数可在自动提交模式和正常模式之间切换。当处于正常模式 (ORA_CommitOff) 时,您可以使用 ORA_Commit() 和 ORA_Rollback() 函数结束事务处理。
如果您在脚本结束时没有提交或回滚,PHP 将进行隐式提交。这与 SQL*Plus 的工作方式一致。
返回页首
在 PHP 中如何处理数据库错误?
在使用 OCI 扩展模块时,可以使用 OCIError() 函数获得带有错误代码、消息、偏移和 SQL 文本的数组。还可以通过将适当的处理作为参数提供给 OCIError(),获得特定会话或游标的错误。没有任何参数时,OCIError() 将返回最后遇到的错误。
<?php
$err = OCIError();
var_dump($err);
print "\nError code = " .$err[code];
print "\nError message = " .$err[message];
print "\nError position = " .$err[offset];
print "\nSQL Statement = " .$err[sqltext];
?>
在使用 ORA 扩展模块时,可以使用 ora_error() and ora_errorcode() 函数来报告错误:
<?php
print "\nError code = " . ora_errorcode();
print "\nError message = " . ora_error();
?>
返回页首
如何从 PHP 调用存储过程?
以下示例创建一个带有 IN 和 OUT 参数的过程。然后执行该过程,并将结果打印出来。
<?php
// Connect to database...
$c=OCILogon("scott", "tiger", "orcl");
if ( !$c ) {
echo "Unable to connect:" . var_dump( OCIError() );
die();
}
// Create database procedure...
$s = OCIParse($c, "create procedure proc1(p1 IN number, p2 OUT number) as " .
"begin" .
" p2 := p1 + 10;" .
" end ;"
OCIExecute($s, OCI_DEFAULT);
// Call database procedure...
$in_var = 10;
$s = OCIParse($c, "begin proc1(:bind1, :bind2); end;");
OCIBindByName($s, ":bind1", $in_var);
OCIBindByName($s, ":bind2", $out_var, 32); // 32 is the return length
OCIExecute($s, OCI_DEFAULT);
echo "Procedure returned value:" . $out_var;
// Logoff from Oracle...
OCILogoff($c);
?>
返回页首
PHP 是否提供 Oracle 连接合并?
不幸的是,PHP 不提供连接合并。您可以使用 ora_plogon() 和 OCIPLogon() 函数调用来打开"持续"的 Oracle 连接。但是,持续连接不能象连接合并那样伸缩。持续连接会对一个过程保持打开状态,但它不允许在不同的过程之间共享连接。
可以使用第三方工具(如 SQL Relay )为 Oracle 和其他数据库启用连接合并。
返回文件页首
Frank Naud_ 是南非的一位 IT顾问/数据库管理员和专家。他是 2001 年获得 Oracle9i 认证专家 (OCP) DBA 认证的前 110 位 IT 专家之一。www.orafaq.net 提供他的更多著作。
|