注:
此外,您还可以在下列步骤中将鼠标放在每个单独的图标上,从而仅加载和查看与该步骤相关的屏幕截图。可以通过单击各个屏幕截图来将其隐藏。
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):' ').'</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 脚本通过调用存储过程 myproc 在 ptab 表中新建了一行。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):' ').'</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;
可以用 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 和 ?> 标记中。
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
将结果数据中的下一行作为数字数组返回