未分类

(OCI8State of Qatar. 使用这些扩大模块,Oracle8i只扶持一种外界LOB类型

29 3月 , 2020  

PHP,即“PHP: Hypertext Preprocessor”,是一种广泛用于 Open
Source并可以嵌入 HTML 的多用途脚本语言。它的语法接近 C、Java 和
Perl,易于学习。该语言的主要目标是让 Web
开发人员快速的书写动态生成的网页,然而,PHP
的功能并不局限于此。PHP普遍被认为可以更快和更有效地实现复杂的编程任务,而且正是因为它的更稳定以及占用更少资源的优点成为开发B/S结构系统的必备的WEB脚本设计语言,扮演着类似中间件的角色,即语法解析与执行。

这些函数允许你存取 Oracle8 和 Oracle7 数据库. 他使用 Oracle8 的点用接口
(OCI8). 使用这个扩展模块,你需要 Oracle8 客户端库文件.
这个扩展模块比标准 Oracle 模块更流畅。他支持用于 Oracle
站位符的全局和本机 PHP 变量。有完整的 LOB, 文件和 ROWID
支持,允许使用用户提供的定义的变量.
在使用这个扩展之前,确认你已经正确的安装了 oracle 用户需要的 Oracle
环境变量, 和用于 daemon 用户的一样. 需要设置的变量大致为如下几个:
ORACLE_HOME
ORACLE_SID
LD_PRELOAD
LD_LIBRARY_PATH
NLS_LANG
ORA_NLS33
(OCI8State of Qatar. 使用这些扩大模块,Oracle8i只扶持一种外界LOB类型。在设置了你的 web 服务器用户的环境变量之后,确认在你的 oracle
组里面加入了 web服务器用户 (nobody, www).
例 1.
<?php
// 作者 sergo@bacup.ru
// 使用参数配置: OCI_DEFAULT 执行命令来延迟执行
OCIExecute($stmt, OCI_DEFAULT);
// 得到数据:
$result = OCIResult($stmt, $n);
if (is_object ($result)) $result = $result->load();
// 进行插入或者更新操作:
$sql = “insert into table (field1, field2) values (field1 = ’value’,
field2 = empty_clob()) returning field2 into :field2″;
OCIParse($conn, $sql);
$clob = OCINewDescriptor($conn, OCI_D_LOB);
OCIBindByName ($stmt, “:field2”, &$clob, -1, OCI_B_CLOB);
OCIExecute($stmt, OCI_DEFAULT);
$clob->save (“some text”);
?>
你可以用同样简单的方法存储程序命令行.
例 2. 用于存储进程(程序)
<?php
// 作者 webmaster@remoterealty.com
$sth = OCIParse ( $dbh, “begin sp_newaddress( :address_id,
’$firstname’,
’$lastname’, ’$company’, ’$address1’, ’$address2’, ’$city’, ’$state’,
’$postalcode’, ’$country’, :error_code );end;” );
// 这个调用用于存储进程 sp_newaddress, 使用 :address_id 开始一个
// in/out 变量和 :error_code 用于输出变量.
// 这样实现捆绑:
OCIBindByName ( $sth, “:address_id”, $addr_id, 10 );
OCIBindByName ( $sth, “:error_code”, $errorcode, 10 );

ORACLE LOB数据模型

在B/S(Browser/Server,浏览器/服务器)应用系统中,需要存储的已不仅仅是简单的文字信息,同时还包括一些图片和音像资料或者是超长的文本。比如开发一套公文系统,公文中的图表、附件等二进制文件或超长文本将无法使用普通的字符或其他类型的数据描述,这就要求后台数据库要有存储这些数据的能力。运用Oracle
LOB对象可实现该功能。

Oracle
LOB是用来存储大量的二进制和文本数据的一种数据类型。目前,它又分为两种类型:内部LOB和外部LOB。内部LOB将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。Oracle8i支持三种类型的内部LOB:BLOB、NCLOB。其中CLOB和NCLOB类型适用于存储超长的文本数据,BLOB字段适用于存储大量的二进制数据,如图像、视频、音频等。目前,Oracle8i只支持一种外部LOB类型,即BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。该类型可帮助用户管理大量的由外部程序访问的文件。

PHP Oracle 8 函数分析

PHP中有两套ORACLE函数扩展库,其中的ORACLE8函数允许访问 Oracle8 和
Oracle7 数据库,这些函数使用了Oracle8 Call-Interface,支持向 Oracle
位置标志符绑定局部和全局 PHP 变量,全面支持 LOB、FILE 和
ROWID,允许用户使用用户自定义的变量,即用户数据库的自定义对象类。

Oracle8函数库中函数OCIFetchInto用于取回一行数据记录放入数组中,该函数的语法描述如下:

int OCIFetchInto(array &result, int [mode])

其中,参数mode可省略,内定值为OCI_NUM。在访问Oracle
LOB时,如果希望返回LOB对象,则mode应设为OCI_ASSOC+OCI_RETURN_LOBS。

函数OCIBindByName用于将PHP变量与Oracle对象进行绑定,从而建立PHP与Oracle之间的数据通讯,该函数语法描述为:

boolean OCIBindByName(int stmt, string ph_name, mixed &variable, int
length, int [type])

其中:参数stmt是经过Oracle解析函数OCIParse解析后的字串指标。参数ph_name即需绑定的ORACLE返回变量名称;参数variable前面一定要加&符号,表PHP变量地址。参数length为变量的长度,若设为-1则使用指定的variable变量的最大值;参数type可省略,其值有OCI_B_FILE、OCI_B_CFILE、OCI_B_CLOB、OCI_金沙国际唯一官网网址 ,B_BLOB及OCI_B_ROWID等数种。值得注意的是,如使用Oracle8中特有的新数据类型LOB/ROWID/BFILE时,需要先执行
OCINewDescriptor()函数,同时必须要将length参数设成 -1。

函数OCINewDescriptor用于初始化新的LOB/FILE描述。该函数语法描述为:

string OCINewDescriptor(int connection , int [type])

其中的type同OCIBindByName函数中的type定义。

必须的环境配置

使用PHP的ORACLE8函数库需要Oracle8客户端库。在使用这个扩展之前,请确认你已经为Oracle
用户和WEB daemon 用户正确设置了 Oracle
环境变量。下面列出了需要设置的环境变量:

ORACLE_HOME #ORACLE安装路径 ORACLE_SID # ORACLE数据库ID
LD_LIBRARY_PATH #LD联接库路径 NLS_LANG #ORALCE地区设置 ORA_www.2979.com ,NLS33
# ORA_NLS33路径
为Linux环境下验证以上变量是否正确,最佳的办法就是分别在oracle用户与nobody下执行:

# env

根据输出的结果,判断上述环境变量是否一致。

在为WEB 服务器用户设置环境变量之后,你还需要将WEB
服务器用户加到oracle组中。

有关ORACLE8客户端和PHP安装设置的详细说明,请参考相关的技术手册。

应用范例

在PHP中上载并将文件存储在ORACLE LOB字段中的应用范例如下:

//LOB对象初始化,获取PHP变量指针

$lob = OCINewDescriptor;

//向有关的文件记录表添加纪录,ORACLE SQL语法解释

$stmt = OCIParse($conn,”update T_FILE set
FILENAME='”.$_FILES[‘FJ1’][‘name’].”‘,FILETYPE='”.$_FILES[‘F1’][‘type’].”‘,FILES=EMPTY_BLOB()
where FILEID=”.$newid.” returning FILES into :lob”);

//绑定LOB变量

OCIBindByName($stmt, ‘:lob’, &$lob, -1, OCI_B_BLOB);

OCIExecute;//执行语句

if{//将表单提交的文件通过lob指针存入ORACLE数据库

OCICommit;

//成功上传

}else{

//未能成功上传

}

OCIFreeDesc;

OCIFreeStatement;

//结束

在PHP中将文件从数据库中提取并下载的应用范例如下:

$stmt = OCIParse($conn,”SELECT * FROM T_ FILE WHERE FILEID =$ID”);

OCIExecute;

if(OCIFetchInto($stmt,$result,OCI_ASSOC+OCI_RETURN_LOBS)){

//输出文件类型信息供浏览器判断

header(“Content-type: “.$result[FILETYPE]);

//输出文件名,浏览器可提示是否打开或下载该文件

header(“Content-Disposition: attachment;
filename=”.$result[FILENAME]);

//以上关于header函数的使用可参考PHP
manual,HTML的文件头信息请参考Internet RFC 2616。

//输出文件流,在此,浏览器获取文件内容,出现正在下载或直接打开文件的提示

echo $result[FILES];

}

OCIFreeStatement;

//结束

以上范例仅是应用的关键语句,并在Linux+PHP+Apache+Oracle8i平台上通过了验证,读者可根据自身需要进行完善和补充。

结束语

本文探讨PHP对ORACLE
LOB访问的实现,仅是PHP在B/S结构系统中基本运用技术所涉及的一个方面。笔者曾对比了JDBC与PHP-OCI两者的执行效率,以JDBC为访问引擎的OAS
HTTP Server(HTTP
Server为apache2.0)的响应速度要逊于建立在Linux+Aache+PHP-OCI平台之上的WEB
Server,这其中当然有Linux的出色表现,但不可否认的是,PHP与OCI的组合是非常优秀的。

由于缺乏ORACLE LOB与PHP
ORACLE8函数库相结合运用的尝试,在开发信息管理系统中,为实现对大型数据文件的管理,PHP在此方面的功能并未得到有效的利用,希望本文对从事PHP数据库技术却遇到此方面难题的程序员会有所帮助。


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图