本教程介绍如何结合使用 PHP 和 Oracle Database 11g。
大约 1 个小时
PHP 是一种流行的 Web 脚本语言,通常用于创建数据库驱动的 Web 站点。如果您要使用 PHP 和 Oracle 数据库开发 Web 应用程序,本教程提供了有关如何在 Oracle 上使用 PHP 的示例,以助您起步。如果您是初次接触 PHP,请参阅附录:PHP 入门,了解 PHP 语言。
为了学习该动手实践讲座,需要安装以下软件:
. |
Oracle Database 11g,用户名为“phphol”,口令(区分大小写)为“welcome”。 |
---|---|
. |
带有 OCI8 1.3 扩展的 PHP 5.3。 |
. |
Apache Web 服务器。 |
. |
本教程使用的所有文件都位于 /home/phphol/public_html 目录中。 |
要创建一个可在 PHP 脚本生命周期内使用的到 Oracle 的连接,执行以下步骤。
. |
查看 $HOME/public_html 目录的 connect.php 文件中包含的以下代码。 <?php // Create connection to Oracle $conn = oci_connect("phphol", "welcome", "//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() 函数包含用户名、口令和连接字符串。在本示例中,使用了 Oracle 的简单连接 (Easy Connect) 连接字符串语法。它由主机名和数据库服务器名组成。 oci_close() 函数关闭连接。脚本结束时,将自动释放所有非显式关闭的标准连接。
|
---|---|
. |
打开一个 Web 浏览器,输入以下 URL 以显示输出: http://localhost/~phphol/connect.php 如果连接成功,则显示“Connected to Oracle!”。
|
. |
查看 $HOME/public_html 目录的 usersess.sql 文件中包含的以下代码。 column username format a30 column logon_time format a18 set pagesize 1000 feedback off echo on select username, to_char(logon_time, 'DD-MON-YY HH:MI:SS') logon_time from v$session where username is not null; exit 这是一个在 SQL*Plus(Oracle 的命令行 SQL 脚本编写工具)中运行的 SQL 脚本文件。该 SQL*Plus 脚本显示当前的数据库会话以及这些会话登录到该数据库的时间。
|
. |
打开一个终端窗口并输入以下命令以运行该 SQL 脚本:注意,您也可以在 SQL Developer 中执行该脚本。 cd $HOME/public_html sqlplus -l -s phphol/welcome @usersess.sql SQL*Plus 脚本列出了当前的数据库会话。只显示对 SQL*Plus 的会话。来自 oci_connect() 函数的 PHP 连接已经关闭。
|
数据库驻留连接池是 Oracle Database 11g 的一个新特性。对 PHP,它允许 Web 应用程序随着站点吞吐量的增长对连接数进行扩充。它还支持多台计算机上的多个 Apache 进程共享一个小规模的数据库服务器进程池。没有 DRCP,标准 PHP 连接必须启动和终止一个服务器进程。一个非 DRCP 持久性连接即使空闲时也将保留数据库服务器资源。本教程介绍新应用程序或现有应用程序如何在不编写和更改任何应用程序逻辑的情况下使用 DRCP。执行以下步骤:
. |
检查 php 是否有 oci8.connection_class 设置。打开一个终端窗口,执行以下命令: php -r 'echo ini_get("oci8.connection_class"), "\n";' 该连接类告诉数据库服务器池这些连接是相关的。不同连接调用之间的会话信息(如默认的数据格式)可能会保留,以改善系统性能。如果之后其他应用程序通过自己的连接类名重用某个池化服务器,则会话信息将作废。
|
---|---|
. |
查看 $HOME/public_html 目录的 query_pooled.php 文件中包含的以下代码。 <?php 将这些代码与 $HOME/public_html 目录的 query_nonpooled.php 文件中的代码进行比较。 <?php
唯一的不同是 query_pooled.php 的简单连接的连接字符串中多了“:pooled”。 请注意,这两个脚本中使用的 oci_pconnect() 调用都会创建到数据库的持久性连接。也就是说,脚本结束后,oci_pconnect() 创建的连接仍然存在,从而避免了为每个脚本建立和断开数据库连接的开销。
|
. |
要运行这两个脚本,需要使用 Apache Benchmark 工具。该命令重复加载一个 Web 页面以测量其性能。在一个终端窗口中执行以下命令: ab -c 150 -t 30 http://localhost/~phphol/query_pooled.php 上面的命令针对该脚本发送了 150 个 Apache 并发请求,每 30 秒重发一次。
|
. |
现在,看一下打开的数据库连接的数量。打开另一个终端窗口,执行以下命令: sqlplus phphol/welcome select username, program from v$session where username = 'PHPHOL'; DRCP 池默认的 MAXSIZE 为 40。您最多可以看到 40 个用户名为 PHPHOL 的连接,这取决于“ab”请求所能处理的 Apache 进程数。运行“ab”的同时可能还需要执行查询以了解池化服务器的工作情况。 Oracle 管理 DRCP 池,达到指定的超时后将缩小 DRCP 池。
|
. |
现在,除了运行非池化脚本外,您将运行同一个命令以比较这两个脚本的不同运行结果。在一个终端窗口中执行以下命令: ab -c 150 -t 30 http://localhost/~phphol/query_nonpooled.php
|
. |
现在,看一下打开的数据库连接的数量。打开另一个终端窗口,执行以下命令: sqlplus phphol/welcome select username, program from v$session where username = 'PHPHOL'; 比上个脚本返回的行数多出不少。带有 httpd@localhost (TNS V1-V3) 的行 对应于一个保持数据库连接打开的运行的 Apache 进程。对于 PHP,Apache 以多进程方式运行,它产生的每个子进程都可处理一个 PHP 脚本。根据 Apache 分配这些进程处理“ab”请求的方式的不同,您在 V$SESSION 中看到的行数可能有所不同。 比较每次运行完成的请求数。您也许希望每个脚本都运行几次以预热这些缓存。 这两个脚本的性能大体相似。这两个文件中使用的工作负载较小时,由于池化服务器的切换开销较小,因此 query_pooled.php 比 query_nonpooled.php 速度稍慢。但非池化脚本导致每个 Apache 进程都打开一个到数据库的单独连接。对大型站点或者内存受限的站点来说,DRCP 的整体优势非常明显。
|
开发 Web 应用程序时的一个常见任务是,查询一个数据库然后在 Web 浏览器中显示结果。您可以使用许多函数查询一个 Oracle 数据库,但查询的基础始终是相同的:
1. | 分析要执行的语句。 | |
2. | 绑定数据值(可选)。 | |
3. | 执行语句。 | |
4. | 从数据库中获取结果。 |
要创建一个简单查询并在 HTML 表格中显示结果,执行以下步骤。
. |
查看 $HOME/public_html 目录的 query.php 文件中包含的以下代码。 <?php // Create connection to Oracle $conn = oci_connect("phphol", "welcome", "//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() 函数将查询结果的一行作为一个关联数组进行检索,包括空值。 htmlentities() 函数将所有类似 HTML 标记的文本进行转义,以便在浏览器中正确显示。
|
---|---|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/query.php 查询结果显示在 Web 浏览器中。 OCI_ASSOC 参数将行作为列名称和列数据的关联数组获取。
|
绑定变量允许您使用新值重新执行语句,避免了重新分析语句的开销。 绑定变量提高了代码可重用性,降低了 SQL 注入攻击的风险。
要在本示例中使用绑定变量,执行以下步骤。
. |
查看 $HOME/public_html 目录的 bind.php 文件中包含的以下代码。 <?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):' ').'</td>'; } print '</tr>'; } print '</table>'; } // Create connection to Oracle $c = oci_connect("phphol", "welcome", "//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); ?>
|
---|---|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/bind.php $myeid 变量绑定到 :eidbv 绑定变量,因此重新执行该查询时,$myeid 的新值将传递到该查询。这使您可以再次执行该语句,而无需用新值对其进行重新分析,从而可提高代码的性能。
|
在 Oracle 数据库中操作数据(插入、更新或删除数据)时,更改的数据或新数据在提交至数据库前仅在数据库会话中可用。更改的数据提交至数据库,然后可供其他用户和会话使用。这是一个数据库事务。
默认情况下,PHP 执行 SQL 语句时会自动提交事务。可以覆盖这一默认设置,使用 oci_commit() 和 oci_rollback() 函数控制事务。在 PHP 脚本结束时,任何未提交的数据将回滚。
单独提交每个更改会额外增加服务器的负载。通常,您希望提交所有数据或者不提交任何数据。进行您自己的事务控制具有性能和数据完整性优势。
要了解在 Oracle 数据库中使用 PHP 时的事务管理,执行以下步骤。
. |
启动 SQL*Plus 并创建一个新表: sqlplus phphol/welcome create table mytable (col1 date);
|
---|---|
. |
查看 $HOME/public_html 目录的 trans_rollback.php 文件中包含的以下代码。 <?php $conn = oci_connect("phphol", "welcome", "//localhost/orcl"); // PHP function to get a formatted date $d = date('j:M:y H:i:s'); // Insert the date into mytable $s = oci_parse($conn, "insert into mytable values (to_date('" . $d . "', 'DD:MON:YY HH24:MI:SS'))"); // Use OCI_DEFAULT to insert without committing $r = oci_execute($s, OCI_DEFAULT); echo "Previous INSERT rolled back as no commit is done before script ends"; ?> OCI_DEFAULT 参数覆盖 oci_execute() 的基本行为。
|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/trans_rollback.php 该脚本在表中插入一行。
|
. |
由于没有任何自动的和显式的提交,因此在脚本完成时,PHP 将回滚数据。为了查看是否有尚未提交的数据,查询该表以查看是否有任何插入的行。在 SQL*Plus 会话中,输入以下命令,从 mytable 表中选择任何行: select to_char(col1, 'DD-MON-YY HH:MI:SS') time from mytable;
|
. |
查看 $HOME/public_html 目录的 trans_commit.php 文件中包含的以下代码。 <?php $conn = oci_connect("phphol", "welcome", "//localhost/orcl"); // PHP function to get a formatted date $d = date('j:M:y H:i:s'); // Insert the date into mytable $s = oci_parse($conn, "insert into mytable values (to_date('" . $d . "', 'DD:MON:YY HH24:MI:SS'))"); // Insert & commits $r = oci_execute($s); // The rollback does nothing: the data has already been committed oci_rollback($conn); echo "Data was committed\n"; ?> 该脚本与 trans1.php 的不同之处在于,插入数据时没有 OCI_DEFAULT。这意味着 oci_execute() 调用将提交新数据。
|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/trans_commit.php 现在,数据已提交。
|
. |
在 SQL*Plus 会话中,输入以下命令,从 mytable 表中选择任何行: select to_char(col1, 'DD-MON-YY HH:MI:SS') time from mytable;
如果您多次重新加载该 PHP 脚本,每执行一次都将插入一行。
|
. |
您可以比较单独提交每行与在事务结束后提交之间的性能差异。 要测试性能差异,查看 $HOME/public_html 目录的 trans_time_commit.php 文件中包含的以下代码。该脚本在每次插入时提交。 <?php function do_insert($conn) { $stmt = "insert into mytable values (to_date('01-JAN-08 10:20:35', 'DD:MON:YY HH24:MI:SS'))"; $s = oci_parse($conn, $stmt); $r = oci_execute($s); // automatically commit } function do_row_check($conn) { $stid = oci_parse($conn, "select count(*) c from mytable"); oci_execute($stid); 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); } // Program starts here $c = oci_connect("phphol", "welcome", "//localhost/orcl"); $starttime = microtime(TRUE); for ($i = 0; $i < 10000; $i++) { do_insert($c); } $endtime = microtime(TRUE) - $starttime; echo "Time was ".round($endtime,3)." seconds<br>"; do_row_check($c); // Check insert done do_delete($c); // cleanup committed rows ?> 将这段代码运行几次,您将了解插入 10,000 行所需的时间。
|
. |
现在,运行 trans_time_explicit.php 脚本。该脚本唯一的区别在于 do_insert() 函数中加入了 OCI_DEFAULT,这样就不会自动提交,并且在插入循环末尾添加了显式提交: ... function do_insert($conn) { $stmt = "insert into mytable values (to_date('01-JAN-08 10:20:35', 'DD:MON:YY HH24:MI:SS'))"; $s = oci_parse($conn, $stmt); $r = oci_execute($s, OCI_DEFAULT); // Don't commit } ... $starttime = microtime(TRUE); for ($i = 0; $i < 10000; $i++) { do_insert($c); } oci_commit($c); $endtime = microtime(TRUE) - $starttime; ... 重新运行该测试。插入时间明显减少。
通常,您希望提交所有数据或者不提交任何数据。定义您自己的事务控制具有性能和数据完整性优势。
|
PL/SQL 是 Oracle 对 SQL 的过程语言扩展。PL/SQL 过程和函数存储在数据库中。使用 PL/SQL 可以让所有数据库应用程序重用逻辑,无论应用程序以何种方式访问数据库。许多与数据相关的操作在 PL/SQL 中的执行速度比将数据提取到一个程序中(例如,PHP)然后再进行处理的速度要快。Oracle 还支持 Java 存储过程。
在本教程中,您将创建一个 PL/SQL 存储过程并在一个 PHP 脚本中调用它。执行以下步骤:
. |
启动 SQL*Plus,用以下命令创建一个新表 ptab: sqlplus phphol/welcome 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); end; /
|
. |
查看 $HOME/public_html 目录的 proc.php 文件中包含的以下代码。查看以下代码: <?php
$c = oci_connect('phphol', 'welcome', '//localhost/orcl');
$s = oci_parse($c, "call myproc('mydata', 123)");
oci_execute($s);
echo "Completed";
?>
|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/proc.php PHP 脚本通过调用存储过程 myproc 在 ptab 表中新建了一行。ptab 表新增了一行,值为“mydata”和 123。 Switch to your SQL*Plus session and query the table to show the new row:
select * from ptab;
|
. |
对 proc.php 进行扩展使其使用绑定变量。将 proc.php 进行如下修改(黑体字表示所作修改): <?php $c = oci_connect('phphol', 'welcome', '//localhost/orcl'); $s = oci_parse($c, "call myproc('mydata', :bv)"); $v = 456; oci_bind_by_name($s, ":bv", $v); oci_execute($s); echo "Completed"; ?> oci_bind_by_name() 函数将 PHP 变量 $v 绑定到“:bv”,通过更改 $v 中的值体验插入值的修改。 重新运行以下 URL: http://localhost/~phphol/proc.php 再次查询该表以显示新行:
select * from ptab;
|
. |
PL/SQL 存储函数通常在 Oracle 数据库中使用。在 SQL*Plus 中,创建一个 PL/SQL 存储函数 myfunc(),以便向 ptab 表中插入一行并且返回插入值的两倍: 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); end; /
|
. |
查看 $HOME/public_html 目录的 func.php 文件中包含的以下代码。查看以下代码: <?php $c = oci_connect('phphol', 'welcome', '//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/~phphol/func.php
|
本节演示一些提高查询性能的方法。执行以下步骤:
. |
首先,创建一个包含大量行的表。查看以下 fetch_prefetch.sql 脚本。 set echo on 在您的 sqlplus 会话中,运行以下命令: connect phphol/welcome @fetch_prefetch
|
---|---|
. |
查看 $HOME/public_html 目录的 fetch_prefetch.php 文件中包含的以下代码。 <?php
|
. |
加载以下 URL 以显示输出: http://localhost/~phphol/fetch_prefetch.php 重新加载几次,看一下平均时间。 可以在 PHP 初始化文件 php.ini 中设置默认的预取大小。在 PHP 5.3 之前,默认预取大小为 10 行。在 5.3 中,为 100 行。您应该为您的应用程序选择一个合适的默认值,针对需要不同值的特定查询使用 oci_set_prefetch()。
|
. |
本节介绍允许从 PL/SQL 过程检索 PHP 数组或向 PL/SQL 过程传递 PHP 数组的 oci_bind_array_by_name() 函数。查看以下 fetch_bulk.sql 脚本。 set echo on 该脚本使用 PL/SQL BULK COLLECT 语句创建从 BIGTAB 获取数据的 PL/SQL 程序包,并以 PL/SQL 数组的形式返回结果。在您的 sqlplus 会话中,运行以下命令: sqlplus phphol/welcome @fetch_bulk
|
. |
查看 $HOME/public_html 目录的 fetch_bulk.php 文件中包含的以下代码。 <?php 该代码调用 PL/SQL 程序包并绑定一个 PHP 变量以存放返回的数据数组。不需要 OCI8 获取调用。 该示例不输出返回的结果。如果您想看到返回结果,在该函数的返回语句前添加“var_dump($res);”。输出显示了您之前运行的 fetch_prefetch.sql 创建的 20 字符的随机数据字符串。
|
. |
加载以下 URL 以显示输出: http://localhost/~phphol/fetch_bulk.php 重新加载几次,看一下平均时间。
|
. |
通过添加 WHERE 子句更改 fetch_bulk.sql 程序包代码以减少获取的行数。 set echo on 在您的 sqlplus 会话中,运行以下命令: sqlplus phphol/welcome @fetch_bulk
|
. |
重新加载以下 URL 以显示输出: http://localhost/~phphol/fetch_bulk.php 尝试不同的行数,观察效果并将结果与之前的 fetch_prefetch.php 脚本进行比较。 根据您的数据、类型、大小及业务需求,测试可帮助您了解哪种获取方法对您的应用程序更快。
|
Oracle 字符大对象 (CLOB) 和二进制大对象 (BLOB) 列(以及 PL/SQL 变量)可包含大量数据。创建这些对象以优化 Oracle 存储的方法有多种。此外,还预先提供了一个程序包 DBMS_LOB,通过它可以轻松地在 PL/SQL 中操作这些对象。
要创建一个小型应用程序以将图像加载并显示到数据库,执行以下步骤。
. |
在执行本节之前,先创建一个表来存储 BLOB。在 SQL*Plus 中,以 phphol 用户身份登录,执行以下命令: sqlplus phphol/welcome create table btab (blobid number, blobdata blob);
|
---|---|
. |
查看 $HOME/public_html 目录的 blobins.php 文件中包含的以下代码。 <?php 该代码显示了嵌入在多个 PHP 块中的 HTML 代码。尤其是,PHP“if”语句包含了 HTML 代码。首次加载该脚本时,显示 HTML 上载表单。PHP 已经填充了 form action 名称以便再次调用同一个脚本。
|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/blobins.php
它显示一个包括 Browse 和 Upload 按钮的 Web 表单。单击 Browse。
|
. |
从 /home/phphol/public_html 目录中选择 oracle.jpg,然后单击 Open。
|
. |
单击 Upload。 form action 再次调用该脚本,但现在设置特殊的变量 $_FILES['lob_upload'] 并上载图片。显示成功的 echo 消息。 图像已上载到 Web 服务器。
|
. |
要显示图像,查看 $HOME/public_html 目录的 blobview.php 文件中包含的以下代码。 <?php $conn = oci_connect("phphol", "welcome", "//localhost/orcl"); $query = 'SELECT BLOBDATA FROM BTAB WHERE BLOBID = :MYBLOBID'; $stmt = oci_parse ($conn, $query); $myblobid = 1; oci_bind_by_name($stmt, ':MYBLOBID', $myblobid); oci_execute($stmt); $arr = oci_fetch_array($stmt, OCI_ASSOC); $result = $arr['BLOBDATA']->load(); header("Content-type: image/JPEG"); echo $result; oci_close($conn); ?>
|
. |
在 Web 浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/blobview.php 确保脚本中没有 echo 语句且“<?php”前面没有任何空格,否则将发送错误的 HTTP 头,造成浏览器无法正确显示图像。如果有问题,将 header() 函数调用注释掉,看看会显示什么。
|
本节介绍在不重新加载整个页面内容的情况下更新部分页面的基本技巧。执行以下任务:
您可以使用 XmlHttpRequest 在不重新加载整个页面内容的情况下更新部分页面。执行以下步骤:
. |
查看 $HOME/public_html 目录的 ajax_id.php 文件中包含的以下代码。该文件只回显传入的参数。 <?php
|
---|---|
. |
在浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/ajax_id.php?id=185
|
. |
查看 $HOME/public_html 目录的 ajax_id.html 文件中包含的以下代码。该文件包含 JavaScript 函数 makeRequest()。 <html>
|
. |
在浏览器中,输入以下 URL 以显示输出: http://localhost/~phphol/ajax_id.html 单击 OK 关闭警报窗口。 注意:如果您使用 Internet Explorer,将需要编辑 ajax_id.html,将 XMLHttpRequest() 调用更改为 ActiveXObject("Msxml2.XMLHTTP") 或 ActiveXObject("Microsoft.XMLHTTP")。 加载该 HTML 页面时,将调用 makeRequest() javascript 函数。它准备了一个 XMLHttpRequest 请求以调用 ajax_id.php。设置回调函数 onreadystatechange。最后,将该请求异步发送给 Web 服务器。 当回调函数收到 Web 服务器请求已返回的通知时,alert() 函数将显示来自 ajax_query.php 的输出。
|
. |
编辑 ajax_id.html,将 185 更改为 186。
|
. |
在浏览器中重新加载该文件。显示新值。单击 OK 关闭警报窗口。
|
PHP 框架(例如 Symfony、Cake 和 Zend Framework)将结构引入 PHP 项目中,从而为 PHP 项目提供了整体体系结构。它们与 eZ Components 之类的组件库一起还提供了丰富的预先构建组件体验,例如,使用 Web 服务或身份验证。
可以框架模型-视图-控制器风格使用 ZFW,也可使用单独的模块。本节介绍 Zend Framework (ZFW) 的数据库组件。
执行以下任务:
您可以使用 Zend 执行一个数据库查询,其结果将显示在页面上。执行以下步骤:
. |
查看 $HOME/public_html 目录的 zfwdb.php 文件中包含的以下代码。该文件只显示一个员工的有关信息。 <?php 它包括来自 Web 服务器文档根目录的 Zend/Db.php。该脚本声明了 Zend_DB 类。然后创建一个 Zend_Db Adapter 类的实例。这可以将实际连接推迟到首次使用,因此可以使您在常用初始块中编写能够初始化连接的应用程序,但是并没有物理上打开数据库连接,除非实际发出了数据库请求。这只是在 Zend_Db 中打开连接的一种方法。fetchAll() 方法返回由查询产生的所有结果。如果只需返回一部分行,则使用相应的 WHERE 子句。
|
---|---|
. |
在浏览器中,输入以下 URL 以显示输出:执行查询时,将返回员工详细信息。 http://localhost/~phphol/zfwdb.php
|
. |
可以使用各种查询模式。编辑 zfwdb.php 文件,在 fetchAll() 方法前添加以下代码行。添加下面黑体的语句。 <?php
|
. |
重新加载 zfwdb.php 文件可看到不同的格式。
|
. |
要将绑定名称的和值的数组传递给 fetchAll(),按照下面的黑体编辑 zfwdb.php 文件: <?php
|
. |
重新加载 zfwdb.php 文件验证是否返回了正确的用户值。
|
可以使用 Zend_Db_Select 类构建一个基于条件逻辑的查询。执行以下步骤:
. |
查看 zfwdb_3.php 文件。将要插入的数据行封装在一个 PHP 数组中。 <?php 该查询的每部分都是分别添加的。 $select->from("EMPLOYEES"); $select->where('employee_id = 185'); 您甚至可以将方法链接在一起: $select->from("EMPLOYEES")->where('employee_id = 185'); 如果只想选择一列,FROM 条件将为: $select->from("EMPLOYEES", "LAST_NAME") 要选择两列,FROM 条件将为: $select->from("EMPLOYEES", array("LAST_NAME", "FIRST_NAME"))
|
---|---|
. |
在浏览器中加载 zfwdb_3.php 文件。 编辑 zfwdb_3.php,体验一下不同的子句。 本节只介绍了 Zend_Db 提供的部分功能,这些功能本身只是 ZFW 的一部分。Zend_Db 与其他组件以及模型-视图-控制器 (MVC) 框架结合使用时,可以更快地构建应用程序。 在使用框架或数据库抽象层实现项目前,您应该考虑它的成熟度、支持和性能特征,从而能够亲自决定适合您业务需要的最佳解决方案。
|
在本教程中,您学习了如何:
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;
可以用 echo 或 print 语句显示字符串和变量。使用 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 时,循环停止。您也可以使用 while 或 do 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 和 ?> 标记中。
<?php echo 'Hello, World!'; ?>
当 Web 服务器配置为通过 PHP 解释程序运行 PHP 文件时,在浏览器中加载脚本将导致执行 PHP 代码,所有输出将传输到浏览器。
PHP 代码块和 HTML 代码块可能是交替的。PHP 代码还可以显式输出 HTML 标记。
<?php require('foo.php'); echo '<h3>'; echo 'Full Results'; echo '</h3>'; $output = bar(123); ?> <table border="1"> <tr> <td> <?php echo $output ?> </td> </tr> </table>
PHP 的许多方面由 php.ini 配置文件中的设置控制。该文件的位置取决于系统。使用 phpinfo() 函数,可以找到其位置、
加载的扩展名列表以及所有初始化设置的值:
<?php phpinfo(); ?>
可以通过编辑 phpl.ini 来更改值,然后重启 Web 服务器。通过使用 ini_set() 函数,还可以在脚本中改变某些设置值。
各种 oci 函数的列表显示如下:
oci_bind_array_by_name |
通过名称将 PHP 数组绑定到 Oracle PL/SQL 数组 |
oci_bind_by_name |
将 PHP 变量绑定到 Oracle 占位符 |
oci_cancel |
取消从游标的读取 |
oci_close |
关闭 Oracle 连接 |
oci_commit |
提交未完成的语句 |
oci_connect |
建立到 Oracle 服务器的连接 |
oci_define_by_name |
在 SELECT 期间将 PHP 变量用于步进定义 |
oci_error |
返回最后发现的错误 |
oci_execute |
执行一条语句 |
oci_fetch_all |
将结果数据的所有行获取到一个数组中 |
oci_fetch_array |
将结果数据中的下一行作为关联数组和/或数字数组返回 |
oci_fetch_assoc |
将结果数据中的下一行作为关联数组返回 |
oci_fetch_object |
将结果数据中的下一行作为对象返回 |
oci_fetch_row |
将结果数据中的下一行作为数字数组返回 |
oci_fetch |
将下一行获取到结果缓冲区中 |
oci_field_is_null |
检查字段是否为 NULL |
oci_field_name |
从语句返回字段的名称 |
oci_field_precision |
告诉字段的精度 |
oci_field_scale |
告诉字段的数值范围 |
oci_field_size |
返回字段的大小 |
oci_field_type_raw |
告诉字段的原始 Oracle 数据类型 |
oci_field_type |
返回字段的数据类型 |
oci_free_statement |
释放与语句或游标关联的所有资源 |
oci_internal_debug |
启用或禁用内部调试输出 |
oci_new_collection |
分配新的集合对象 |
oci_new_connect |
建立到 Oracle 服务器的新连接 |
oci_new_cursor |
分配和返回新游标(语句句柄) |
oci_new_descriptor |
对新的空 LOB 或 FILE 描述文件进行初始化 |
oci_num_fields |
返回语句中的结果列数 |
oci_num_rows |
返回语句执行期间受影响的行数 |
oci_parse |
准备要执行的 Oracle 语句 |
oci_password_change |
更改 Oracle 用户的口令 |
oci_pconnect |
使用持久性连接连接到 Oracle 数据库 |
oci_result |
从获取的行返回字段的值 |
oci_rollback |
回滚未完成的事务 |
oci_server_version |
返回服务器版本 |
oci_set_prefetch |
设置要预取的行数 |
oci_statement_type |
返回 OCI 语句的类型 |
关于 Oracle | | 招聘 | 联系我们 | 网站地图 | 法律声明 | 使用条款 | 您的隐私权利 |