PHP,即“PHP: Hypertext Preprocessor”,是一种广泛用于 Open Source(开放源代码)并可以嵌入 HTML 的多用途脚本语言。它的语法接近 C、Java 和 Perl,易于学习。该语言的主要目标是让 Web 开发人员快速的书写动态生成的网页,然而,PHP 的功能并不局限于此。PHP普遍被认为可以更快和更有效地实现复杂的编程任务,而且正是因为它的更稳定以及占用更少资源的优点成为开发B/S结构系统的必备的WEB脚本设计语言,扮演着类似中间件的角色,即语法解析与执行。
ORACLE LOB数据模型
在B/S(Browser/Server,浏览器/服务器)应用系统中,需要存储的已不仅仅是简单的文字信息,同时还包括一些图片和音像资料或者是超长的文本。比如开发一套公文系统,公文中的图表、附件等二进制文件或超长文本将无法使用普通的字符或其他类型的数据描述,这就要求后台数据库要有存储这些数据的能力。运用Oracle LOB对象可实现该功能。
Oracle LOB是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据)。目前,它又分为两种类型:内部LOB和外部LOB。内部LOB将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。Oracle8i支持三种类型的内部LOB:BLOB(二进制数据)、CLOB(单字节字符数据)、NCLOB(多字节国家字符数据)。其中CLOB和NCLOB类型适用于存储超长的文本数据,BLOB字段适用于存储大量的二进制数据,如图像、视频、音频等。目前,Oracle8i只支持一种外部LOB类型,即BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。该类型可帮助用户管理大量的由外部程序访问的文件。
PHP Oracle 8 函数分析
PHP中有两套ORACLE函数扩展库,其中的ORACLE8函数允许访问 Oracle8 和 Oracle7 数据库,这些函数使用了Oracle8 Call-Interface(OCI8),支持向 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(文字LOB)、OCI_B_BLOB(位元LOB)及OCI_B_ROWID(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_NLS33 # ORA_NLS33路径
为Linux环境下验证以上变量是否正确,最佳的办法就是分别在oracle用户与nobody下执行:
# env
根据输出的结果,判断上述环境变量是否一致。
在为WEB 服务器用户设置环境变量之后,你还需要将WEB 服务器用户(nobody、 www)加到oracle组中。
ORACLE8クライアントおよびPHPのインストール設定の詳細な手順については、関連する技術マニュアルを参照してください。
応用例
PHPでORACLE LOBフィールドにファイルをアップロードして保存する応用例は以下の通りです:
//LOBオブジェクトの初期化、PHP変数ポインタの取得
$lob = OCINewDescriptor($conn, OCI_D_LOB)
//関連するファイルレコードテーブルにレコードを追加します、ORACLE SQL構文の説明
$stmt = OCIParse($conn,"update T_FILE set FILENAME='".$_FILES['FJ1']['name'].
" ',FILETYPE='".$_FILES['F1']['type']."',FILES=EMPTY_BLOB() where FILEID=".$newid." :lob に FILES を返します);
//Tie LOB 変数を定義します
OCIBindByName($stmt, ':lob', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt, OCI_DEFAULT);// ステートメントを実行します
if($lob-> savefile( $F1)){//フォームによって送信されたファイルを、LOB ポインターを介して ORACLE データベースに保存します
OCICommit($conn);
//アップロードに成功しました
}else{
//アップロードに失敗しました
}
OCIFreeDesc($lob);
OCIFreeStatement($stmt);
//End
PHP でデータベースからファイルを抽出してダウンロードする応用例は次のとおりです。
$stmt = OCIParse($ conn,"SELECT * FROM T_ FILE WHERE FILEID =$ID");
OCIExecute($stmt);
if(OCIFetchInto($stmt,$result,OCI_ASSOC+OCI_RETURN_LOBS)){
//ファイルタイプ情報を出力するブラウザの判断用
header("Content-type: ".$result[FILETYPE]);
//出力ファイル名、ブラウザはファイルを開くかダウンロードするかをプロンプトできます
header("Content-Disposition:attachment ; filename=" .$result[FILENAME]);
//上記の header 関数の使用方法については、PHP のマニュアルを参照してください。HTML ファイルのヘッダー情報については、インターネット RFC 2616 を参照してください。
//出力ファイルストリーム。ここでは、ブラウザがファイルの内容を取得し、ファイルがダウンロード中または開かれていることを示すプロンプトが直接表示されます
echo $result[FILES];
OCIFreeStatement($stmt);
// 終了
上記の例は、アプリケーションの主要なステートメントにすぎず、Linux+PHP+Apache+Oracle8i プラットフォームで検証されています。読者は、必要に応じて改良したり補足したりできます。
結論
この記事では、PHP による ORACLE LOB へのアクセスの実装について説明します。これは、B/S 構造システムにおける PHP テクノロジの基本的なアプリケーションの 1 つの側面にすぎません。筆者は、JDBC と PHP-OCI の実行効率を比較しましたが、アクセス エンジンとして JDBC を使用した OAS HTTP サーバー (HTTP サーバーは apache2.0) の応答速度は、Linux+Aache+PHP-OCI 上に構築されたものよりも遅くなります。もちろん、WEB サーバーは Linux の優れたパフォーマンスを備えていますが、PHP と OCI の組み合わせが非常に優れていることは否定できません。
情報管理システムの開発において、大規模なデータファイルの管理を実現するために、ORACLE LOBとPHP ORACLE8関数ライブラリを組み合わせる試みが不足しているため、この分野でのPHPの機能が有効に活用されていないと思います。この記事は、情報管理システムの開発に携わっている人にとって役立ちます。これは、PHP データベース テクノロジに問題があるプログラマにとって役立ちます。
http://www.bkjia.com/PHPjc/313861.html