添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

将鼠标置于此图标上 可以加载和查看本教程的所有屏幕截图。 (警告:因为此操作会同时加载所有屏幕截图,所以网速较慢时,响应时间可能会比较长。)

注: 此外,您还可以在下列步骤中将鼠标放在每个单独的图标上,从而仅加载和查看与该步骤相关的屏幕截图。可以通过单击各个屏幕截图来将其隐藏。

PHP 是一种流行的 Web 脚本语言,通常用于创建数据库驱动的 Web 站点。如果您要使用 PHP 和 Oracle 数据库开发 Web 应用程序,本教程提供了有关如何在 Oracle 上使用 PHP 的示例,以带您起步。如果您是初次接触 PHP,请参阅 附录:PHP 入门 ,了解 PHP 语言。

开始本教程之前,您应该:

安装 Oracle 数据库 11g 或 Oracle 数据库快捷版。

安装 PHP 5.2.4。

配置 Linux Apache 服务器。

下载 php.zip 文件,并将其解压缩到 Apache 服务器可以找到文件的目录(即 $HOME/public_html )中。

有关本前提条件部分中的第 1-3 步的安装指导,可在 OTN 上找到。

<localhost> 是本教程中的主机名。如果不同,则将该值更改成您的主机名。此外,本教程中使用 HR HRPWD 是假设的口令。如果您打算使用快捷版而非 Oracle 数据库 11g,则需要将整个教程的 SID 从 localhost/orcl 更改为 localhost/XE

要创建一个可在 PHP 脚本生命周期内使用的到 Oracle 的连接,执行以下步骤。

查看 $HOME/public_html 目录的 connect.php 文件中包含的以下代码。

// Create connection to Oracle $conn = oci_connect("hr", "hrpwd", "//localhost/orcl"); if (!$conn) { $m = oci_error(); echo $m['message'], "\n"; exit; else { print "Connected to Oracle!"; // Close the Oracle connection oci_close($conn);

oci_connect() 函数包含连接信息。在本示例中,使用简化的连接字符串。

如果脚本结束时会自动关闭连接,则不需要 oci_close( ) 函数。

打开一个 Web 浏览器,输入以下 URL 以显示输出:

http://localhost/~phplab/connect.php

如果连接成功,则显示“Connected to Oracle!”。

如果创建数据库连接过程中出现问题,则显示错误“Error connecting to Oracle”。

开发 Web 应用程序时的一个常见任务是,查询一个数据库然后在 Web 浏览器中显示结果。您可以使用许多函数来查询一个 Oracle 数据库,但查询的基础始终是相同的:

分析 要执行的语句。 绑定 数据值(可选) 执行 语句。 从数据库中 获取 结果。

要创建一个简单查询并在 HTML 表格中显示结果,执行以下步骤。

查看 $HOME/public_html 目录的 query.php 文件中包含的以下代码。

// Create connection to Oracle $conn = oci_connect("hr", "hrpwd", "//localhost/orcl"); $query = 'select * from departments'; $stid = oci_parse($conn, $query); $r = oci_execute($stid); // Fetch the results in an associative array print '<table border="1">'; while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS+OCI_ASSOC)) { print '<tr>'; foreach ($row as $item) { print '<td>'.($item?htmlentities($item):' ').'</td>'; print '</tr>'; print '</table>'; // Close the Oracle connection oci_close($conn);

oci_parse() 函数分析语句。

oci_execute() 函数执行经过分析的语句。

oci_fetch_array() 函数将查询结果作为一个关联数组进行检索,包括空值。

在 Web 浏览器中,输入以下 URL 以显示输出:

http://localhost/~phplab/query.php

查询结果显示在 Web 浏览器中。

返回主题列表

到 Oracle 的持久连接可以在多个脚本上重用。对 Oracle 环境所做的更改将反映在所有访问该连接的脚本中。本主题通过创建一个持久连接,然后用另一个脚本更改 Oracle 环境来对此进行了演示。

要创建一个可在多个 PHP 脚本中重用的持久连接,执行以下步骤:

查看 $HOME/public_html 目录的 pconnect.php 文件中包含的以下代码。

// Create a persistent connection to Oracle // Connection will be reused over multiple scripts $conn = oci_pconnect ("hr", "hrpwd", "//localhost/orcl"); if (!$conn) { $m = oci_error(); echo $m['message'], "\n"; exit; else { print "Connected to Oracle!"; // Close the Oracle connection
oci_close($conn);

oci_pconnect() 函数创建了一个到 Oracle 的持久连接。

使用 oci_close() 函数不会关闭持久连接,在该脚本中是多余的。

在 Web 浏览器中,输入以下 URL 以显示输出:

http://localhost/~phplab/pconnect.php       

现在已经创建了持久连接。该连接仍可用于那些使用相同登录凭证并且由相同的 http 进程支持的脚本。

查看 $HOME/public_html 目录的 usersess.sql 文件中包含的以下代码。

column username format a30
column logon_time format a18
set pagesize 1000 feedback off echo on
alter session set nls_date_format = 'DD-MON-YY HH:MI:SS';
select username, logon_time from v$session where username is not null;

您现在已经创建了一个要在 SQL*Plus 中运行的 SQL*Plus(Oracle 的命令行 SQL 脚本工具)脚本文件。 该 SQL*Plus 脚本更改了数据库的国家语言字符日期格式,显示当前的数据库会话。日期格式更改只与 SQL*Plus 会话有关,用于规定登录时间的输出格式。

打开一个终端窗口,输入以下命令。注意,您也可以在 SQL Developer 中执行脚本。

cd $HOME/public_html
sqlplus system/oracle@//localhost/orcl
@usersess.sql 

SQL*Plus 脚本列出当前数据库会话。PHP 脚本创建的会话仍处于活动状态,在结果的第一行显示为用户名 HR。尽管调用了 oci_close() 函数,但这并不会关闭持久连接,该连接可以用于其他脚本。

为了说明该持久连接正由其他 PHP 脚本重用且会话设置相同,查看 $HOME/public_html 目录的 pconnect2.php 文件中包含的以下代码。

// Function to execute a query function do_query($conn, $query) {
$stid = oci_parse($conn, $query);
oci_execute($stid);
oci_fetch_all($stid, $res);
echo "<pre>";
var_dump($res);
echo "</pre>";
} // Create a persistent connection to Oracle $c = oci_pconnect("hr", "hrpwd", "//localhost/orcl"); // Query the database system date do_query($c, "select sysdate from dual"); // Change the NLS Territory $s = oci_parse($c, "alter session set nls_territory=germany"); $r = oci_execute($s); // Query the database system date again do_query($c, "select sysdate from dual");

该脚本将创建一个新的持久连接,或者使用相同的登录凭证重用现有的持久连接。

然后,该脚本使用 do_query() 函数查询并获取数据库系统日期。它使用 var_dump 调试函数输出包含日期查询结果的 PHP 变量的值和结构。

然后,该脚本更改国家语言地区设置以适合德国的格式显示输出,再次调用 do_query() 函数以再次显示数据库系统日期。

在 Web 浏览器中,输入以下 URL 以显示输出:

http://localhost/~phplab/pconnect2.php 

注意,当 ALTER SESSION 命令更改为其他地区时,你将看到两个查询日期格式的区别。

查看使用持久连接重新加载脚本的效果。您可能希望执行该操作多次,直至重用原始 PHP 会话(Apache 进程)。两个查询现在使用相同的新的日期格式。这表明已重用该连接,当后面的脚本运行时,仍然会设置原来脚本中设置的日期格式。该连接仍然处于活动状态(持久的),可供其他使用相同登录凭证的 PHP 脚本使用。如果脚本更改为使用一个标准连接,将始终输出两种不同的时间格式。

您应该了解持久会话期间您进行的环境更改,因为它们可能还会影响其他脚本。但事务不会跨 PHP 脚本,未提交的数据将在脚本结束处回滚。

再次运行 SQL*Plus 脚本 usersess.sql ,查看哪些连接处于打开状态。

现在,许多由 HR 用户创建的数据库会话都处于打开状态。这将显示当前可用的持久会话。在 Linux 上,Apache 作为多个独立进程运行。PHP 不会在进程间共享任何信息(包括连接)。由于您每次运行一个脚本时,该脚本都可能由其他 httpd 进程执行,因此当您使用 oci_pconnect() 时,您最后可能有多个打开的数据库连接。

返回主题列表

在 Oracle 数据库中操作数据(插入、更新或删除数据)时,更改的数据或新数据在提交到数据库之前仅在数据库会话中可用。更改的数据提交至数据库后,可供其他用户和会话使用。这是一个数据库事务。
单独提交每个更改会额外增加服务器的负载。通常,您希望提交所有数据或者不提交任何数据。执行自己的事务控制具有性能和数据完整性优势。
默认情况下, oci_execute() 函数立即提交更改。
如果数据无法自动提交,或者在您使用 oci_commit() 将数据显式提交给数据库之前不能用于其他会话,则使用 OCI_DEFAULT 参数。您也可用 oci_rollback() 进行回滚。
Oracle 建议您将 OCI_DEFAULT 用作一个通常包含多个数据库交互的事务(即 DML)。
要通过 Oracle 数据库了解 PHP 中的事务管理,执行以下步骤。

在 SQL*Plus 会话中,输入以下命令,以 HR 用户身份登录到数据库并创建一个新表:

connect hr/hrpwd@//localhost/orcl
create table mytable (col1 date);

查看 $HOME/public_html 目录的 trans1.php 文件中包含的以下代码。

<?php
    echo "<pre>";
    // Execute a query
    function do_query($conn)
    {
      $stid = oci_parse($conn,
          "select to_char(col1, 'DD-MON-YY HH:MI:SS') from mytable");
      oci_execute($stid, OCI_DEFAULT);
      oci_fetch_all($stid, $res);
      foreach ($res as $v) {
        var_dump($v);
      }
    }
    // Create a database connection
    function do_connect()
    {
      $conn = oci_new_connect("hr", "hrpwd", "//localhost/orcl");
      return($conn);
    }
    $d = date('j:M:y H:i:s');
    // Create a connection
    $c1 = do_connect();

    // Insert the date into mytable
    $s = oci_parse($c1,
        "insert into mytable values (to_date('"
        . $d . "', 'DD:MON:YY HH24:MI:SS'))");

    // Use OCI_DEFAULT to execute the statement without committing
    $r = oci_execute($s, OCI_DEFAULT);

    // Query the current session/connection
    echo "Query using connection 1<br>\n";
    do_query($c1);

    // Create a new connection and query the table contents
    $c2 = do_connect();
    echo "<br>Query using connection 2<br>\n";
    do_query($c2);
    echo "</pre>";
    ?>

该脚本中使用了两个连接。
该脚本使用 oci_new_connect() 创建一个唯一的、非持久性的数据库连接,然后将日期插入到 mytable 表中并进行查询。
然后,该脚本再创建一个唯一的数据库连接,再次查询此表以显示对第二个连接可见的内容。

在 Web 浏览器中,输入以下 URL 以显示输出:

http://localhost/~phplab/trans1.php

该脚本使用 $c1 连接向表中插入一行。

数据尚未提交到数据库,因为每个 oci_execute() 调用都使用 OCI_DEFAULT,没有调用 oci_commit()。其他数据库用户目前还无法看到该行。使用第二个连接 $c2 的查询返回一个空数组。

由于没有进行任何提交,因此在脚本结束时,PHP 将回滚数据。为了查看是否有尚未提交的数据,查询该表以查看是否有任何插入的行。在 SQL*Plus 会话中,输入以下命令,从 mytable 表中选择任何行:

select * from mytable;

查看 $HOME/public_html 目录的 trans2.php 文件中包含的以下代码。

<?php
    echo "<pre>";

    // Execute a query
    function do_query($conn)       $stid = oci_parse($conn,           "select to_char(col1, 'DD-MON-YY HH:MI:SS') from mytable");       oci_execute($stid, OCI_DEFAULT);       oci_fetch_all($stid, $res);       foreach ($res as $v) {         var_dump($v);     // Create a database connection     function do_connect()       $conn = oci_new_connect("hr", "hrpwd", "//localhost/orcl");       return($conn);     $d = date('j:M:y H:i:s');     // Create a connection     $c1 = do_connect();     // Insert the date into mytable     $s = oci_parse($c1,         "insert into mytable values (to_date('"         . $d . "', 'DD:MON:YY HH24:MI:SS'))");     $r = oci_execute($s);  // no OCI_DEFAULT means automatically commit     // Query the current session/connection     echo "Query using connection 1<br>\n";     do_query($c1);     // Create a new connection and query the table contents     $c2 = do_connect();     echo "<br>Query using connection 2<br>\n";     do_query($c2);     echo "</pre>";

该脚本与 trans1.php 的不同之处在于,插入数据时没有 OCI_DEFAULT。这意味着将提交新数据。

在 Web 浏览器中,输入以下 URL 以显示输出:

http://localhost/~phplab/trans2.php

现在,数据已经提交,因此两个查询都将返回表中的新行。
重新加载页面。您每次进行重新加载时,都会看到表中添加了许多行。

      $stid = oci_parse($conn,           "select count(*) c from mytable");       oci_execute($stid, OCI_DEFAULT);       oci_fetch_all($stid, $res);       echo "Number of rows: ", $res['C'][0], "<br>";     function do_delete($conn)       $stmt = "delete from mytable";      $s = oci_parse($conn, $stmt);       $r = oci_execute($s);     function do_insert($conn)       $d = date('j:M:y H:i:s');       $stmt = "insert into mytable values (to_date('"               . $d . "', 'DD:MON:YY HH24:MI:SS'))";       $s = oci_parse($conn, $stmt);       $r = oci_execute($s);     $c = oci_connect("hr", "hrpwd", "//localhost/orcl");     $start = currTime();     for ($i = 0; $i < 10000; $i++) {       do_insert($c);     $et = elapsedTime($start);     echo "Time was ".round($et,3)." seconds<br>";     do_query($c);  // Check insert done     do_delete($c); // cleanup committed rows

运行这段代码几次,您将了解插入 10,000 行所需的时间。

现在,运行 trans4.php 脚本。该脚本唯一的区别在于已插入 do_insert() 函数 OCI_DEFAULT,这样就不会自动提交,并且在插入循环末尾添加了显式提交:

function do_insert($conn) { $d = date('j:M:y H:i:s'); $stmt = "insert into mytable values (to_date('" . $d . "', 'DD:MON:YY HH24:MI:SS'))"; $s = oci_parse($conn, $stmt); $r = oci_execute($s, OCI_DEFAULT); $c = oci_connect("hr", "hrpwd", "//localhost/orcl"); $start = currTime(); for ($i = 0; $i < 10000; $i++) { do_insert($c); oci_commit($c); $et = elapsedTime($start);

重新运行该测试。插入时间减少。

通常,您希望提交所有数据或者不提交任何数据。进行您自己的事务控制具有性能和数据完整性优势。

返回主题列表

从 Oracle 数据库中获取数组数据的方式有多种。您可以将数组作为关联数组和/或数字数组进行获取。

要了解如何使用数组获取参数,执行以下步骤。

第一部分显示如何使用 oci_fetch_array() 的默认输出获取数组,它是通过关联索引和数字索引获取数组的。

查看 $HOME/public_html 目录的 fetch.php 文件中包含的以下代码。查看以下代码:

<?php
echo "<pre>";
$conn = oci_connect("hr", "hrpwd", "//localhost/orcl");
$query = 'select * from employees where employee_id = 101';
$stid = oci_parse($conn, $query);
oci_execute($stid);
while ($row = oci_fetch_array($stid)) {
var_dump($row); // display PHP's representation of $row
}
oci_close($conn);
echo "</pre>";
?>

在 Web 浏览器中,输入以下 URL 以显示输出:

http://localhost/~phplab/fetch.php

该输出显示结果既包含关联索引又包含数字索引。虽然这可以为您处理结果的方式提供更大的灵活性,但会产生很大的网络和内存开销。

而您可能希望仅将数组作为一个关联数组获取。本部分显示如何只获取一个关联数组。

oci_fetch_array() 调用更改为如下内容:

oci_fetch_array($stid, OCI_ASSOC)

重新运行以下 URL:

http://localhost/~phplab/fetch.php

如输出所示,OCI_ASSOC 参数将数组作为一个关联数组获取。

最后一个选项是将数组作为一个数字数组获取。本部分显示如何只获取一个数字数组。

再次将 oci_fetch_array() 调用更改为如下内容:

oci_fetch_array($stid, OCI_NUM)

重新运行以下 URL:

http://localhost/~phplab/fetch.php

输出显示 OCI_NUM 参数将数组作为一个数字数组获取。

您还可以使用其他 oci_fetch_array() 参数和组合,如:

  • oci_fetch_array($stid, OCI_BOTH),它同时返回关联索引和数字索引
  • oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS),它返回一个关联索引,包括 NULL。
  • PHP 文档包含获取选项的完整列表。

    返回主题列表

    绑定变量允许您使用新值重新执行查询,避免了重新分析语句的开销。 绑定变量提高了代码可重用性,降低了 SQL 注入攻击的风险。

    要在本示例中使用绑定变量,执行以下步骤。

    查看 $HOME//public_html 目录的 bind.php 文件中包含的以下代码。

       function do_fetch($myeid, $s)      // Fetch the results in an associative array      print '<p>$myeid is ' . $myeid . '</p>';      print '<table border="1">';      while ($row = oci_fetch_array($s, OCI_RETURN_NULLS+OCI_ASSOC)) {          print '<tr>';          foreach ($row as $item) {              print '<td>'.($item?htmlentities($item):'&nbsp;').'</td>';          print '</tr>';      print '</table>';    // Create connection to Oracle    $c = oci_connect("hr", "hrpwd", "//localhost/orcl");    // Use bind variable to improve resuability, and to    // remove SQL Injection attacks.    $query = 'select * from employees where employee_id = :eidbv';    $s = oci_parse($c, $query);    $myeid = 101;    oci_bind_by_name($s, ":EIDBV", $myeid);    oci_execute($s);    do_fetch($myeid, $s);    // Redo query without reparsing SQL statement    $myeid = 104;    oci_execute($s);    do_fetch($myeid, $s);    // Close the Oracle connection    oci_close($c);

    返回主题列表

    PL/SQL 是 Oracle 对 SQL 的过程语言扩展。PL/SQL 存储过程和函数存储在数据库中,因此其访问速度非常快。使用 PL/SQL 存储过程允许所有数据库应用程序重用逻辑,无论应用程序以何种方式访问数据库。许多与数据相关的操作在 PL/SQL 中的执行速度比将数据提取到一个程序中(例如,PHP)然后再进行处理的速度快。

    Oracle 允许 PL/SQL 和 Java 存储过程。在本教程中,您将创建一个 PL/SQL 存储过程并在一个 PHP 脚本中调用它。执行以下步骤:

    启动 SQL*Plus,用以下命令创建一个新表 ptab

    sqlplus hr/hrpwd@//localhost/orcl
    create table ptab (mydata varchar(20), myid number);

    在 SQL*Plus 中,使用以下命令创建一个存储过程 myproc,以将数据插入到 ptab 表中:

    create or replace procedure
    myproc(d_p in varchar2, i_p in number) as
    begin
      insert into ptab (mydata, myid) values (d_p, i_p);
    $c = oci_connect('hr', 'hrpwd', '//localhost/orcl');
    $s = oci_parse($c, "call myproc('mydata', 123)");
    oci_execute($s);
    echo "Completed";
        

    在 Web 浏览器中,输入以下 URL 以显示输出:

    http://localhost/~phplab/proc.php

    PHP 脚本通过调用存储过程 myprocptab 表中新建了一行。ptab 表新增了一行,值为“mydata”和 123。

    切换到您的 SQL*Plus 会话,查询表以显示新的行: select * from ptab;
    $c = oci_connect('hr', 'hrpwd', '//localhost/orcl'); $s = oci_parse($c, "call myproc('mydata', :bv)"); $v = 123; oci_bind_by_name($s, ":bv", $v); oci_execute($s); echo "Completed";

    使用 oci_bind_by_name() 将一个 PHP 变量 $v 绑定到“:bv”,并尝试通过更改 $v 中的值来更改插入的值。

    重新运行以下 URL:

    http://localhost/~phplab/proc.php

    再次查询该表以显示新的行: select * from ptab;

    除了存储过程之外,通常还使用 PL/SQL 存储函数。在 SQL*Plus 中,创建一个 PL/SQL 存储函数 myfunc() ,以向 ptab 表中插入一行,并返回插入的 myid 值的两倍

    create or replace function
       myfunc(d_p in varchar2, i_p in number) return number as    begin      insert into ptab (mydata, myid) values (d_p, i_p);      return (i_p * 2);    $c = oci_connect('hr', 'hrpwd', '//localhost/orcl');    $s = oci_parse($c, "begin :bv := myfunc('mydata', 123); end;");    oci_bind_by_name($s, ":bv", $v, 10);    oci_execute($s);    echo $v, "<br>\n";    echo "Completed";

    由于要返回一个值,因此将 oci_bind_by_name() 的可选长度参数设置为 10,这样 PHP 就可以分配能够存储 10 位的正确内存量了。

    重新运行以下 URL:

    http://localhost/~phplab/func.php

    首先需要创建一个简单表和新过程 myproc()。该过程接受一个数组,并使用 Oracle 的快速批量插入“FORALL”语句插入数组中的所有元素。查看 $HOME/public_html 目录的 proc2.sql 文件中的代码。

    drop table ptab; create table ptab(name varchar2(20)); create or replace package mypkg as type arrtype is table of varchar2(20) index by pls_integer; procedure myproc(p1 in out arrtype); end mypkg; create or replace package body mypkg as procedure myproc(p1 in out arrtype) is begin forall i in indices of p1 insert into ptab values (p1(i)); end myproc; end mypkg;

    在终端窗口中,执行以下命令:

    sqlplus hr/hrpwd@//localhost/orcl
    @proc2

    查看 $HOME/public_html 目录的 coll.php 文件中包含的以下代码。

    <?php
    function do_query($conn)
    {
    echo "<pre>";
    $stid = oci_parse($conn, "select * from ptab");
    oci_execute($stid, OCI_DEFAULT);
    oci_fetch_all($stid, $res);
    var_dump($res);
    echo "</pre>";
    }
    for ($i = 0; $i < 10; $i++) {
    $a[] = 'value '.$i;
    }
    $c = oci_connect("hr", "hrpwd", "//localhost/orcl");
    $s = oci_parse($c, "BEGIN mypkg.myproc(:c1); END;");
    oci_bind_array_by_name($s, ":c1", $a, count($a), -1, SQLT_CHR);
    oci_execute($s);
    do_query($c)
    ?>

    这将在 $a 中创建一个字符串数组。然后,将该数组绑定到 PL/SQL 过程的参数。

    在 Web 浏览器中,输入以下 URL 以显示输出:

    http://localhost/~phplab/coll.php

    PTAB 表查询这些值,以验证它们已插入。

    返回主题列表

    使用 Oracle 数据库错误处理功能时,PHP 函数 oci_error() 很有用。

    如果没找到错误,oci_error() 连接错误会返回 FALSE 并且无需传入参数。如果发生连接错误,oci_error() 将 Oracle 错误作为一个关联数组返回。这适用于所有连接函数 (oci_connect()oci_pconnect()oci_new_connect())。

    处理分析错误或执行错误时,传入 oci_error() 的资源句柄。

    要实践一些简单的错误处理,执行以下步骤。

    查看 $HOME/public_html 目录的 errors.php 文件中包含的以下代码。

    <?php
    //Create connection to Oracle
    $conn = oci_connect("hr", "hrpwd", "//localhost/orcl");
    if (!$conn) {
    // No argument needed for connection errors.
    // To generate an error here, change the connection parameters to be invalid.
    $e = oci_error();
    print "There was a database connection error: " . htmlentities($e['message']);
    exit;
    }
    // To generate an error here, change the * to an another character, such as %.
    $query = "select * from departments";
    $stid = oci_parse($conn, $query);
    if (!$stid) {
    // For parsing errors, pass the connection resource
    $e = oci_error($conn);
    print "There was a statement parsing error: " . htmlentities($e['message']);
    exit;
    }
    $r = oci_execute($stid);
    if (!$r) {
    // For execution and fetching errors, pass the statement resource
    // To generate an error here, change $query to be an invalid query.
    $e = oci_error($stid);
    echo "<p>";
    print "There was a statement execution error: <strong>" . htmlentities($e['message']). "</strong><br>";
    print "The error is located at character " . htmlentities($e['offset']+1) ." of the query:
    <strong>". htmlentities($e['sqltext']). "</strong><br>";
    echo "</p>";
    exit;
    }
    // Fetch the results in an associative array
    print '<table border="1">';
    while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS+OCI_ASSOC)) {
    print '<tr>'; foreach ($row as $item) { print '<td>'.($item?htmlentities($item):'&nbsp;').'</td>';
    }
    print '</tr>';
    }
    print '</table>'; // Close the Oracle connection
    oci_close($conn);
    ?>

    @ 函数前缀可以禁止所有 PHP 错误。这与将 php.ini 文件设置为不显示错误一样,但仅与您在其上使用该前缀的函数相关。使用 @ 前缀可以消除前面的错误处理示例中显示的 PHP 错误。要演示此功能,将 oci_execute() 更改为:

    $r=@oci_execute($stid);

    重新运行以下 URL:

    http://localhost/~phplab/errors.php

    PHP 错误已禁止,但脚本中的错误处理代码仍然显示 Oracle 错误。

    返回主题列表

    Oracle 字符大对象 (CLOB) 和二进制大对象 (BLOB) 列(以及 PL/SQL 变量)可以包含大量的数据。创建这些对象以优化 Oracle 存储的方法有多种。此外,还预先提供了一个程序包 DBMS_LOB,通过它可以轻松地在 PL/SQL 中操作这些对象。

    要创建一个小型应用程序以将图像加载并显示到数据库,执行以下步骤。

    在执行本部分之前,先创建一个表来存储 BLOB。在 SQL*Plus 中,以 HR 用户身份登录,执行以下命令:

    create table btab (blobid number, blobdata blob);

    查看 $HOME/public_html 目录的 blobins.php 文件中包含的以下代码。

    <?php
    $myblobid = 1; // should really be a unique id e.g. a sequence number
    if (!isset($_FILES['lob_upload'])) {
    ?>
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST" enctype="multipart/form-data">
    Image filename: <input type="file" name="lob_upload">
    <input type="submit" value="Upload">
    </form>
    <?php
    }
    else {
    $conn = oci_connect("hr", "hrpwd", "//localhost/orcl");
    // Delete any existing BLOB
    $query = 'DELETE FROM BTAB WHERE BLOBID = :MYBLOBID';
    $stmt = oci_parse ($conn, $query);
    oci_bind_by_name($stmt, ':MYBLOBID', $myblobid);
    $e = oci_execute($stmt, OCI_COMMIT_ON_SUCCESS);
    if (!$e) {
    die;
    }
    else {
    $conn = oci_connect("hr", "hrpwd", "//localhost/orcl");
    // Delete any existing BLOB
    $query = 'DELETE FROM BTAB WHERE BLOBID = :MYBLOBID';
    $stmt = oci_parse ($conn, $query);
    oci_bind_by_name($stmt, ':MYBLOBID', $myblobid);
    $e = oci_execute($stmt, OCI_COMMIT_ON_SUCCESS);
    if (!$e) {
    die;
    }
    oci_free_statement($stmt);
    // Insert the BLOB from PHP's temporary upload area
    $lob = oci_new_descriptor($conn, OCI_D_LOB);
    $stmt = oci_parse($conn, 'INSERT INTO BTAB (BLOBID, BLOBDATA) '
    .'VALUES(:MYBLOBID, EMPTY_BLOB()) RETURNING BLOBDATA INTO :BLOBDATA');
    oci_bind_by_name($stmt, ':MYBLOBID', $myblobid);
    oci_bind_by_name($stmt, ':BLOBDATA', $lob, -1, OCI_B_BLOB);
    oci_execute($stmt, OCI_DEFAULT);
    if ($lob->savefile($_FILES['lob_upload']['tmp_name'])) {
    oci_commit($conn);
    echo "BLOB uploaded";
    }
    else {
    echo "Couldn't upload BLOB\n";
    }
    $lob->free();
    oci_free_statement($stmt);
    }
    }
    ?>

    在 Web 浏览器中,输入以下 URL 以显示输出:

    http://localhost/~phplab/blobins.php

    它显示一个包括 Browse 和 Upload 按钮的 Web 表单。单击 Browse

    /home/oracle/public_html 目录中选择 oracle.jpg,然后单击 Open

    要显示图像,查看 $HOME/public_html 目录的 blobview.php 文件中包含的以下代码。

    <?php
    $myblobid = 1;
    $conn = oci_connect("hr", "hrpwd", "//localhost/orcl");
    // Now query the uploaded BLOB and display it
    $query = 'SELECT BLOBDATA FROM BTAB WHERE BLOBID = :MYBLOBID';
    $stmt = oci_parse ($conn, $query);
    oci_bind_by_name($stmt, ':MYBLOBID', $myblobid);
    oci_execute($stmt);
    $arr = oci_fetch_assoc($stmt);
    $result = $arr['BLOBDATA']->load();
    header("Content-type: image/JPEG");
    echo $result;
    oci_free_statement($stmt);
    oci_close($conn);
    ?>

    另一种创建 XML 表单关系数据的方法是使用 PL/SQL 程序包 DBMS_XMLGEN()(返回一个 CLOB)。xml2.php 文件中的代码将完成以下操作:

    a) 检索部门内 ID 为 30 的员工名字,并将 XML 标记的输出存储在 $mylob

    $q = "select dbms_xmlgen.getxml('

    select first_name
    from employees
    where department_id= 30') xml
    from dual";

    $s = oci_parse($c, $q);
    oci_execute($s);
    $res = oci_fetch_row($s);
    $mylob = $res[0]->load(); // treat as LOB descriptor

    b) 显示 $mylob 的内容

    echo htmlentities($mylob);

    c) 使用 PHP 的 SmpleXML 函数将 CLOB 转换成一个 XML 数组。

    $xml = (array) simplexml_load_string($mylob);

    返回主题列表

    PHP 是一种动态类型的脚本语言。它在 Web 应用程序中很常见,但可用于运行命令行脚本。基本的 PHP 语法简单易学。它具有熟悉的循环、测试和赋值结构。每行以分号结束。

    字符串可以包含在单引号或双引号中:

    'A string constant'
    "another constant"

    变量名以美元符号为前缀。类似双引号字符串内的变量将扩展为:

    "A value appears here: $v1"

    也可使用句点将字符串和变量连接在一起。

    'Employee ' . $ename . ' is in department ' . $dept

    变量不需要声明类型:

    $count = 1;
    $ename = 'Arnie';

    数组可以具有数字索引或关联索引:

    $a1[1] = 3.1415;
    $a2['PI'] = 3.1415;

    可以用 echoprint 语句显示字符串和变量。使用 printf() 还可以实现格式化输出。

    echo 'Hello, World!';
    echo $v, $x;
    print 'Hello, World!';
    printf("There is %d %s", $v1, $v2);

    var_dump() 函数对于调试很有帮助。

    var_dump($a2);

    假定上面指定的值为 $a2,输出如下所示:

    array(1) {
      ["PI"]=>
      float(3.1415)
    

    可以通过测试和循环来控制代码流。PHP 还具有一个 switch 语句。if/elseif/else 语句如下所示:

    if ($sal > 900000) {
      echo 'Salary is way too big';
    elseif ($sal > 500000) {
      echo 'Salary is huge';
      else {
      echo 'Salary might be OK';
    

    这还会显示代码块是如何包含在括号中。

    传统的循环为:

    for ($i = 0; $i < 10; $i++) {
      echo $i;
    

    这将输出数字 0 到 9。$i 的值在每次迭代后递增。当测试条件值为 false 时,循环停止。您也可以使用 whiledo while 结构进行循环。

    foreach 命令对于数组迭代很有帮助:

    $a3 = array('Aa', 'Bb', 'Cc');
    foreach ($a3 as $v) {
      echo $v;
    

    这会依次将 $v 设置为数组中的每个元素。

    可能会定义如下所示的函数:

    function myfunc($p1, $p2) {
      echo $p1, $p2;
      return $p1 + $p2;
    

    函数可能具有可变数量的参数,可能返回值,也可能不返回值。可以使用以下代码调用该函数:

    $v3 = myfunc(1, 3);

    函数调用可能会出现在函数定义之前。

    可以使用 include()require() 语句将子文件包括在 PHP 脚本中。

    include("foo.php");
    require("bar.php");

    如果没找到该脚本,require() 将生成严重错误。

    注释要么是一行:

    // a short comment

    要么是多行:

    A longer comment

    PHP 脚本包含在 <?php?> 标记中。

    echo 'Hello, World!';

    当 Web 服务器配置为通过 PHP 解释程序运行 PHP 文件时,在浏览器中加载脚本将导致执行 PHP 代码,所有输出将传输到浏览器。

    PHP 代码块和 HTML 代码块可能是交替的。PHP 代码还可以显式输出 HTML 标记。

    require('foo.php'); echo '<h3>'; echo 'Full Results'; echo '</h3>'; $output = bar(123); <table border="1"> <?php echo $output ?> </table>

    PHP 的许多方面由 php.ini 配置文件中的设置控制。文件的位置取决于系统。使用 phpinfo() 函数,可以找到其位置、
    加载的扩展名列表以及所有初始化设置的值:

    phpinfo();

    可以通过编辑 phpl.ini 或使用 Zend Core for Oracle 控制台然后重新启动 Web 服务器来更改值。通过使用 ini_set() 函数,可以在脚本中改变某些值。

    各种 oci_xxx 函数的列表包括:

    oci_fetch_all

    将结果数据的所有行获取到一个数组中

    oci_fetch_array

    将结果数据中的下一行作为关联数组和/或数字数组返回

    oci_fetch_assoc

    将结果数据中的下一行作为关联数组返回

    oci_fetch_object

    将结果数据中的下一行作为对象返回

    oci_fetch_row 将结果数据中的下一行作为数字数组返回