Oracle 技术网
Oracle/PHP 常见问题解答

作者 Frank Naudé

主题

  • PHP 是什么,它与 Oracle 有什么关系?
  • OCI 与 ORA 扩展模块之间有什么不同?
  • 如何配置 PHP 来使用 Oracle?
  • 如何连接 Oracle?
  • 为什么会遇到错误 "Call to undefined function:ora_logon()/ ocilogon()"?
  • 如何从 PHP 选择插入更新删除数据?
  • 在 PHP 中如何处理数据库事务?
  • 在 PHP 中如何处理数据库错误?
  • 如何从 PHP 调用存储过程?
  • PHP 是否提供 Oracle 连接合并?
  • 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 数据库:

    • 从 www.php.net 下载 PHP,按照每个 install.txt 文件进行安装,并测试是否一切运行正常。

    • 在您的机器上安装 Oracle 客户端(或服务器)软件,并配置 SQL*Net 来连接您的数据库。

    • 编辑 php.ini 文件并取消以下两行的注释(仅当您的版本带有预编译的扩展模块时):
      ;extension = php_oci8.dll
      ;extension = php_oracle.dll
      
      ... 否则,使用以下选项编译 PHP:
      --with-oracle=/path/to/oracle/home/dir
      --with-oci8=/path/to/oracle/home/dir
      

    • 确保您的 "extension_dir" 参数(在 php.ini 中)指向以上扩展文件所在的位置。

    • 编写一个小程序来测试连接性 - 可参见下一个问题。

  • 返回页首

  • 如何连接 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 选择插入更新删除数据?

    以下示例演示如何通过 INSERTUPDATEDELETE 语句选择和处理数据:

    <?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 提供他的更多著作。

    寄送此页面
    Printer View 打印机视图