ADODB 手冊


 
 

PHP ADODB1.99版手冊 (修正版)

 

PHP ADODB 1.99版手冊中文翻譯 <修正版>

ADODB

PHP 在數據庫的支持上是很令人稱道的,幾乎所有的知名數據庫系統都有對應的函數群支持,而且支持的很完整。但很不幸的,每一群數據庫支持函數無論在名稱或參數結構上,都有很大的差異,這使得PHP的系統開發者在面臨更換數據庫時,總會覺得痛苦萬分。難道這個問題就沒有解決方法嗎?呵呵,當然有,答案就是我現在要介紹的 ADODB 這個PHP物件。

ADODB提供了完整的方法和屬性讓工程師去控制數據庫系統,更棒的是你只要記得它的功能就好了,因為不同的數據庫系統,只要修改一個屬性值就可以了,ADODB會自動依據設定取用正確的PHP函數。此外,最多再配合數據庫系統修改修改SQL指令,你的PHP系統就可以在最短的時間內更換到另一個數據庫系統了,如果在編寫程序時,對SQL指令能做妥善規划,那就更快了。

經過以上的介紹,相信你已經對ADODB的功用有所了解,以下為ADODB的詳細介紹。

取得ADODB

你可以在 http://php.weblogs.com/ADOdb 取得最新版的ADODB。我在編寫本文時,最新版本是1.99版,版權采BSD-Style及LGPL雙軌制,換句話就是Freeware,沒有什么限制。但在取得ADODB后,最好還是要看一下相關版權說明及用法,並和本文對照一下,以免錯誤。

使用ADODB

基本上使用ADODB是相當容易的,取得壓縮文件后解開,我建議將整個內容都解到ADODB的目錄里。然后你可以一邊參考本文,一邊研究里面的范例,就放在里面的test目錄下。

由於ADODB附上的說明十分完整詳實,以下的說明大部份來自ADODB的readme.htm,這里不是全部的內容,我把一些我認為沒有用的內容都去掉了,像版本差異說明、何編寫支持ADODB的驅動程序等與應用無關的部份。想要了解全部內容的讀者還是可以自己去參考 readme.htm。


簡介

由於PHP的數據庫存取函數沒有標准化,所以我們需要一組函數庫或是類別來隱藏不同數據庫函數介面間的差異,讓我們可以很簡單的去切換數據庫,而這,就是ADODB的目的。

ADODB目前支持MySQL, Oracle, Microsoft SQL Server, Sybase, Sybase SQL Anywhere, Informix, PostgreSQL, FrontBase, Interbase (Firebird 及 Borland 版本), Foxpro, Access, ADO 和 ODBC。ADODB也有透過ODBC成功連接Progress及DB2的報告,我們希望能有更的人提供驅動介面來支持更多的數據庫。

PHP4支持連接變量(session variables),使用者可以透過ADODB保存連接信息,以達成真正的可攜性及彈性,相關的用法及信息請自行參考ADOdb-session.php這個范例。

另外,如果要編寫一個具有高度可移植性的SQL碼,也可以參閱 http://php.weblogs.com/portable_sql 這篇文章。

特色

  • 對熟悉Windows的工程師而言,ADODB很容易使用,因為ADODB里的很多功能和Microsoft的ADO很像。

  • 與其它的PHP數據庫類別不同,它們大多集中在處理與 select 指令有關的東西,而ADODB對於 inserts 及 update 也提供額外的支持,並且可以很快的連接到多數據庫。所提供的方法更擴及日期的掌握,字串的連接及字串標記字元差異處理(在某些數據庫間字串的連接和標記符號是有差異的)

  • 類型對照系統是內建的,所以我們可以設定或描述像CHAR,TEXT及STRING在不同的數據庫間其實是相同的數據類型。

  • 更容易去移植,因為所有與數據庫相依的程序碼被都隱藏在后端,所以使用者不再需要去移植類別里的邏輯。

  • 支持 PHP4 連接變量,請參考 ADOdb-session.php。

安裝

首先要確定你所使用的PHP版本是 4.01pl2 或是之后的版本(因為ADODB使用到了 require_once及include_once兩個函數)。解壓縮全部的文件到你的Web服務器可以存取的一個目錄里。

要測試ADODB你需要一個數據庫,開啟 testdatabase.inc.php 這個文件,並且修改連接參數,以適合你所使用的數據庫。這個程序會建立一個新的數據表在你的數據庫中,以支持我們提供的測試程序及范例。

就這樣,你安裝好了。

啟動ADODB

當要執行ADODB時,至少有兩個文件要被載進來,第一個是 ADOdb.inc.php ,這里面包含了所有數據庫類中要被使用的函數。而對數據庫實作的程序碼則被置放在ADOdb-????.inc.php文件里。

例如說,要連接一個mysql數據庫:

include('/path/to/set/here/ADOdb.inc.php');
$conn = &ADONewConnection('mysql');

無論何時你需要連接到一個數據庫時,你必需使用ADONewConnection()函數建立了一個連接物件。ADONewConnection接受一個選擇性參數, <database-name-here>。如果沒有參數被指定,它將會使用被 ADOLoadCode() 所載入的最后一個數據庫。 NewADOConnection() 是另一個相同的函數。

當你建立好一個連接物件時,你並沒有真的連接上你的數據庫。你仍需要使用 $conn->Connect() 或者 $conn->PConnect() 兩個方法來完成真正的連接。

你可以參考教學手冊里的范例,對上面的說明做更深入的了解。

支持的數據庫

名稱

測試狀態

數據庫

RecordCount() 支持與否

需安裝的驅動程序

操作系統

access

B

Microsoft Access/Jet. 需要建立一個 ODBC/DSN。

Y/N

ODBC

Windows only

ado

B

一般未經特別指定的數據庫系統, 透過ADO,允許不設定 DSN連接,使用OLEDB以提供較佳的效能。

? 視數據庫而定

ADO or OLEDB provider

Windows only

ado_access

B

Microsoft Access/Jet 透過ADO,允許不設定 DSN連接,使用OLEDB以提供較佳的效能。

Y/N

ADO or OLEDB provider

Windows only

ado_mssql

B

Microsoft SQL Server 透過ADO,允許不設定 DSN連接,使用OLEDB以提供較佳的效能。

Y/N

ADO or OLEDB provider

Windows only

db2

C

DB2. 可以透過ODBC獲得可以信賴的運作效果。

Y/N

DB2 CLI/ODBC interface

Unix and Windows. Unix install hints.

vfp

A

Microsoft Visual FoxPro,需要建立一個ODBC/DSN

Y/N

ODBC

Windows only

fbsql

C

FrontBase.

Y

?

Unix and Windows

ibase

B

Interbase 6或更早的版本。有些使用者報告必需使用如下的方式連接
$db->PConnect('localhost:c:/ibase/employee.gdb', "sysdba", "masterkey")目前沒有支持 Affected_Rows 方法

Y/N

Interbase client

Unix and Windows

firebird

C

interbase的Firebird版本

Y/N

Interbase client

Unix and Windows

borland_ibase

C

Borland 的Interbase 6.5 或更新版

Y/N

Interbase client

Unix and Windows

informix

C

Informix

Y/N

Informix client

Unix and Windows

mssql

A

Microsoft SQL Server 7.也可以和Microsoft SQL Server 2000運作的很好。但在日期格式上仍有一些問題。例如在日期時間的返回值上,就不會返回秒數數值。

Y/N

Mssql client

Unix and Windows.
Unix install howto
.

mysql

A

MySQL 不支持交易處理

Y/N

MySQL client

Unix and Windows

mysqlt 或 maxsql

A

MySQL 支持交易處理

Y/N

MySQL client

Unix and Windows

oci8

A

Oracle 8/9. 支持比 oracle 驅動程序還多的功能 (例如: Affected_Rows). 在連接之前,你可能需要先配好環境變量('ORACLE_HOME=...')

有兩個方式進行連接,用服務器的IP或服務名稱:
PConnect('serverip:1521','scott','tiger','service')
PConnect('', 'scott', 'tiger', 'tnsname').

Y/N

Oracle client

Unix and Windows

oci8po

A

Oracle 8/9 可攜式驅動程序

Y/N

Oracle client

Unix and Windows

odbc

A

標准 ODBC

用 PConnect('DSN','user','pwd').連接。

? depends on database

ODBC

Unix and Windows. Unix hints.

odbc_mssql

C

用 ODBC 連接 MSSQL

Y/N

ODBC

Unix and Windows.

odbc_oracle

C

用 ODBC 連接 ORACLE

Y/N

ODBC

Unix and Windows.

oracle

C

支持舊的 Oracle 7 client API. 不支持 $ADODB_FETCH_MODE.

Y/N

Oracle client

Unix and Windows

postgres

A

PostgreSQL 不支持 LIMIT 指令.

Y

PostgreSQL client

Unix and Windows.

postgres7

A

PostgreSQL 支持 LIMIT 及其它版本 7 功能

Y

PostgreSQL client

Unix and Windows.

sqlanywhere

C

Sybase SQL Anywhere. 

Y/N

SQL Anywhere ODBC client

?

sybase

C

Sybase.

Y/N

Sybase client

Unix and Windows. Unix hints.

 

測試狀態欄的代碼說明如下:

A=已經經過很多人驗證及測試,可靠度最高。
B=已經測試並使用了,但可能仍有一些功能沒有達成。
C=使用者自行配置或試用的驅動程序,可能沒有完全支持ADODB的功能。

"RecordCount()支持與否",指的是RecordCount()函數是否會返回用SELECT指令取得的記錄筆數(不支持時傳回-1)。如果這個字段的值出現了 Y/N ,那表示當全域變量 $ADODB_COUNTER=true 時,會以模擬的方式取得,而這是預設值。要注意的是,如果你預測記錄筆數會很大時,最好把這個值設為false,也就是關掉這個模擬功能,因為這會耗掉非常多的內存,以做為快取之用。由於這個變量在每次執行時都會檢查,所以你可以選擇性的使用或不使用。

所有支持$ADODB_FETCH_MODE的數據庫都支持 ADODB_FETCH_NUM(以字段順序存取) 及 ADODB_FETCH_ASSOC(以字段名稱存取),兩種模式。而將值設為 ADODB_FETCH_DEFAULT(數據庫預設模式存取),則是由數據庫的功能來決定的,所以不具備可攜性,而 ADODB_FETCH_BOTH(雙模式存取) 也一樣。


學習手冊

范例 1: Select 指令

任務:連接到 Access 的 Northwind DSN,然后在每一列顯示頭2個字段。(Northwind 北風數據庫,在ODBC設定的DSN,是Access的標准范例數據庫)

在這個范例中,我們建立一個 ADOConnection 物件,它代表了和數據庫的連接。連接是以 PConnect 函數來初始化的,然后會持續的連接着。任何時候我們要查詢數據庫時,我們就調用 ADOConnection.Execute() 函數,這將會返回一個 ADORecordSet物件。事實上它只是一個指向在fields[]陣列中,目前記錄的指標,我們使用MoveNext()來在記錄間移動。

注意:另一個很有用的函數 SelectLimit 並沒有在這個范例里使用,這個函數允許我們去限制顯示的數據筆數。

<?
include('ADOdb.inc.php');       # 載入ADODB
$conn = &ADONewConnection('access');    # 建立一個連接
$conn->PConnect('northwind');   # 連接到 MS-Access 北風數據庫
$recordSet = &$conn->Execute('select * from products');
if (!$recordSet) 
        print $conn->ErrorMsg();
else
while (!$recordSet->EOF) {
        print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';
        $recordSet->MoveNext();
}

$recordSet->Close(); # 選擇性執行
$conn->Close(); # 選擇性執行

?>

在這個例子中,$recordSet返回了存在$recordSet->fields陣列里,目前所指向的記錄。以字段編號為索引,起始值為0。我們使用MoveNext()函數來移動到下一筆記錄,當到了最后一筆時,EOF屬性會被設定為true。當Execute()函數執行有錯誤時,會返回一個false值,而不是一個recordset物件。

$recordSet->fields[]陣列是由PHP數據庫擴充函數庫所產生的。有一些數據庫擴充函數庫僅支持以編號來進行索引,而不支持以字段名為索引。要強迫使用字段名索引,也就是要使用關連式陣列,請使用 $ADODB_FETCH_MODE 全域變量來設定。當一個數據集被Execute()或是SelectLimit()函數建立時,都會保存而且使用儲如此類的設定模式。

       $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
        $rs1 = $db->Execute('select * from table');
        $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
        $rs2 = $db->Execute('select * from table');
        print_r($rs1->fields); # shows array([0]=>'v0',[1] =>'v1')
        print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')

上面的范例說明,如果要以順序來存取字段,就將 $ADODB_FETCH_MODE 的值設為 ADODB_FETCH_NUM,要以關連式陣列(以字段名)存取字段,就要將值設為 ADODB_FETCH_ASSOC。

要取得在被選到的記錄筆數,你可以使用$recordSet->RecordCount()方法。注意,如果不能確定得到的記錄筆數,會返回 -1 。

范例 2: 進階的 Select 指令(使用 Field 物件)

任務:選取一個數據表,顯示最前面的二欄。如果第二欄是一個日期或時間型態字段,將它格式化成US格式。

<?
include('ADOdb.inc.php');       
$conn = &ADONewConnection('access');    
$conn->PConnect('northwind');   
$recordSet = &$conn->Execute('select CustomerID,OrderDate from Orders');
if (!$recordSet) 
        print $conn->ErrorMsg();
else
while (!$recordSet->EOF) {
        $fld = $recordSet->FetchField(1);
        $type = $recordSet->MetaType($fld->type);

        if ( $type == 'D' || $type == 'T')
                print $recordSet->fields[0].' '.
                        $recordSet->UserDate($recordSet->fields[1],'m/d/Y').'<BR>';
        else 
                print $recordSet->fields[0].' '.$recordSet->fields[1].'<BR>';

        $recordSet->MoveNext();
}
$recordSet->Close(); # optional
$conn->Close(); # optional

?>

在這個例子中,我們使用 FetchField() 函數來檢查第二個字段的數據類型。這將會返回一個至少有三個字段的物件,字段說明如下:

  • name: 字段名

  • type: 字段的數據原生類型native field type of column

  • max_length: 字段的最大長度,部份數據庫像MySQL,並不返回字段的正確值,以這個例子而言,就會返回 -1 。

然后我們使用 MetaType() 去轉換原生類型成通用類型,目前通用類型定義如下:

  • C:  character 字段,應該使用 <input type="text"> 標記來取值。

  • X: 文字字段(Text) , 長文字字段,使用 <textarea> 標記來顯示數據。

  • B: Blob 字段或者大型的二位元物件(像程序,圖檔等)。

  • D: 日期字段

  • T: 時間字段

  • L: 邏輯字段(真假值)或位元字段

  • N: 數字字段,包含自動進位、編號、整數、浮點數、實數等。

  • R: 序列字段,包含了序列、自動增進整數,只對被選擇的數據庫作用。

如果對應類型是日期或時間,那你可以使用 UserDate() 函數來設定輸出的日期格式。這個函數會轉換 PHP SQL 日期字串格式為使用者定義的格式。 另一個使用MetaType()的時機是在進行SQL新增或更新指令時,數據格式驗證用。

范例 3: 新增

新增一筆記錄到訂單數據表,里面包含了日期和字串,為了能被數據庫正常存取,字串必需校正,以避免部份標記字元。例如:有單引號的字串,John's。

<?
include('ADOdb.inc.php');       # load code common to ADOdb
$conn = &ADONewConnection('access');    # create a connection

$conn->PConnect('northwind');   # connect to MS-Access, northwind dsn
$shipto = $conn->qstr("John's Old Shoppe");

$sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";
$sql .= "values ('ANATR',2,".$conn->DBDate(time()).",$shipto)";

if ($conn->Execute($sql) === false) {
        print 'error inserting: '.$conn->ErrorMsg().'<BR>';
}
?>

在這個范例中,我們看見了ADODB更進一步的日期及標點符號的處理方式。Unix 日期時間標示(長整數)被DBDate()格式化成Access可以接受的格式,而帶了縮寫符號的 John's Old Shoppe 則被 qstr() 函數處理成 John''s Old Shoppe 字串,以被數據庫合法存取。

觀察 Execute 指令的錯誤處理。如果 Execute() 執行有錯誤發生時,會傳回 False 值。而最后的錯誤信息可以由  ErrorMsg() 來顯示。

附記:php_track_errors旗標可以被啟動,以便將錯誤信息保存起來。

范例 4: 除錯

<?
include('ADOdb.inc.php');       # load code common to ADOdb
$conn = &ADONewConnection('access');    # create a connection
$conn->PConnect('northwind');   # connect to MS-Access, northwind dsn
$shipto = $conn->qstr("John's Old Shoppe");
$sql = "insert into orders (customerID,EmployeeID,OrderDate,ShipName) ";
$sql .= "values ('ANATR',2,".$conn->FormatDate(time()).",$shipto)";
$conn->debug = true;
if ($conn->Execute($sql) === false) print 'error inserting';
?>

在上面的例子中,我們藉由設定 debug=true 來啟動除錯模式。這將會在執行指令時會先將SQL指令顯示,並且會顯示所有的錯誤信息,而不需要去調用 ErrorMsg() 。顯示數據集的部份,可以參考 rs2html() 范例。

其它的請參考自定錯誤處理的說明。

范例 5: MySQL及選單

連接到MySQL數據庫agora ,並且從SQL命令中建立一個 <select> 選單,<option>的標題是第一個字段,返回值是第二個字段。

<?
include('ADOdb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('mysql');  # create a connection
$conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->Execute($sql);
print $rs->GetMenu('GetCust','Mary Rosli');
?>

Here we define a menu named GetCust, with the menu option 'Mary Rosli' selected. See GetMenu(). We also have functions that return the recordset as an array: GetArray(), and as an associative array with the key being the first column: GetAssoc().

這里,我們定義了一個名為GetCust的選單,預設值是'Mary Rosli'。相關說明請參考 GetMenu() 。我們也將數據集以陣列返回的方式寫在 GetArray()方法里。而另外返回關聯式陣列的方法則使用 GetAssoc() ,其中第一個字段是這個字段的鍵值。

在 1.50 版以后的 ADODB 里,是使用公共變量 $ADODB_FETCH_MODE 來設定返回的陣列是以編號或是關連式字串做索引。

范例 6: 一次連接兩個數據庫

<?
include('ADOdb.inc.php');     # 載入 ADOdb
$conn1 = &ADONewConnection('mysql');  # 建立一個 mysql 連接
$conn2 = &ADONewConnection('oracle');  # 建立一個 oracle 連接

$conn1->PConnect($server, $userid, $password, $database);
$conn2->PConnect(false, $ora_userid, $ora_pwd, $tnsname);

$conn1->Execute('insert ...');
$conn2->Execute('update ...');
?>

范例 7: 產生 Update 及 Insert 的SQL指令

ADODB 1.31版起,新增了兩個數據集函數:GetUpdateSQL()及GetInsertSQL()。這允許你在執行了像"SELECT * FROM table query WHERE..."這樣的查詢函數后,建立一個 $rs->fields復本,改變這些字段,然后自動產生出更新或是新增的SQL指令。

以下我們展示如何運用這些函數,我們將存取一個數據表,帶有下列字段:(ID,FirstName,LastName,Created)。在這些函數被執行前,你需要藉由一個對數據表的查詢指令(select)來初始化一個數據集。

<?
#==============================================
#  GetUpdateSQL() 及 GetInsertSQL() 范例碼
#==============================================
include('ADOdb.inc.php');
include('tohtml.inc.php');

#==========================
# 以下的程序碼測試新增狀態

$sql = "SELECT * FROM ADOXYZ WHERE id = -1"; 
# 從數據庫中查詢出一個空的數據集

$conn = &ADONewConnection("mysql");  # 建立一個連接
$conn->debug=1;
$conn->PConnect("localhost", "admin", "", "test"); # 連接到 MySQL, 數據庫名稱為 test
$rs = $conn->Execute($sql); # 執行查詢,並取得一個空的數據集

$record = array(); # 初始化一個陣列,以便存放記錄數據供新增用

# 設定記錄中的字段值
$record["firstname"] = "Bob";
$record["lastname"] = "Smith";
$record["created"] = time();

# 傳入空的數據集及字段數據陣列到GetInsertSQL函數中,以執行功能
# 這個函數將會依傳入的數據,返回一個全格式的 INSERT SQL指令

$insertSQL = $conn->GetInsertSQL($rs, $record);

$conn->Execute($insertSQL); # 將記錄挿入數據庫中

#==========================
# 以下的程序碼測試更新狀態

$sql = "SELECT * FROM ADOXYZ WHERE id = 1"; 
# 選擇一筆記錄以便更新

$rs = $conn->Execute($sql); # 執行這個查詢,並取得一個存在的記錄來更新

$record = array(); # 初始化一個陣列,以存放要更新的數據

# 設定字段里的值
$record["firstname"] = "Caroline";
$record["lastname"] = "Smith"; # 更新 Caroline的姓由 Miranda 變成 Smith

# 傳入這個只有單一記錄的數據集以及含有數據的陣列到 GetUpdateSQL函數里
# 函數將會返回一個具有正確 WHERE 條件的 UPDATE(更新) SQL 指令
$updateSQL = $conn->GetUpdateSQL($rs, $record);

$conn->Execute($updateSQL); # 更新數據庫中的記錄
$conn->Close();
?>

范例 8: 使用上一筆及下一筆實作卷動

我們使用HTTP取得 $next_page 變量,以追蹤要跳去那一頁並且保存目前頁碼在 session 變量 $curr_page 里。

我們調用連接物件的 PageExecute()函收去取得我們要的數據集,然后我們使用數據集的 AtFirstPage() 及 AtLastPage() 函數去決定是否顯示下一頁和上一頁按鈕。

<?php
include_once('ADOdb.inc.php');
include_once('tohtml.inc.php');
session_register('curr_page');

$db = NewADOConnection('mysql');
$db->Connect('localhost','root','','xphplens');
$num_of_rows_per_page = 10;
$sql = 'select * from products';

if (isset($HTTP_GET_VARS['next_page']))
 $curr_page = $HTTP_GET_VARS['next_page'];
if (empty($curr_page)) $curr_page = 1; ## at first page

$rs = $db->PageExecute($sql, $num_of_rows_per_page, $curr_page);
if (!$rs) die('Query Failed');

if (!$rs->EOF && (!$rs->AtFirstPage() || !$rs->AtLastPage())) {
        if (!$rs->AtFirstPage()) {
?>
<a href="<?php echo $PHPSELF,'?next_page=',$rs->AbsolutePage() - 1 ?>">Previous page</a>
<?php
        }
        if (!$rs->AtLastPage()) {
?>
<a href="<?php echo $PHPSELF,'?next_page=',$rs->AbsolutePage() + 1 ?>">Next page</a>
<?php
        }
        rs2html($rs);
}
?>

以上的程序碼可以在 testpaging.php 范例里找到。

使用自定錯誤處理及 PEAR_Error

在之前的版本,你可以使用像 $con->debug=true ; 這樣的設定來進行除錯。但在 1.50 版后,我們提供了另一種方法來處理錯誤狀態。我們讓工程師可以使用 ADODB 的自訂錯誤處理程序功能。

ADODB 提供了兩種自訂處理方式,你可以配合你的的需要而修訂。第一個方法放在 ADOdb-errorhandler.inc.php 文件里。這讓你可以使用標准的 PHP 函數 err_reporting 去控制要顯示怎樣的錯誤信息及 trigger_error 去調用 PHP 預設的錯誤處理程序。

引入了上述文件后(ADOdb-errorhandler.inc.php),當發生了下列的錯誤后,將會使得 trigger_error($errorstring,E_USER_ERROR)被調用。

  1. Connect() 或 PConnect() 執行失敗時。

  2. 執行 SQL 指令的函數失敗時,如 Execute() 或 SelectLimin() 。

  3. GenID() 進入了無限回圈時。

這里的 $errorstring 變量是由 ADODB 所產生的。而且會包含了有用的除錯信息,類似於隨后會建立的 error.log 數據。所以,為了要能正確提供除錯信息,你要在建立 ADOConnection 物件前,就把 ADOdb-errorhandler.inc.php 引入到程序碼中。

If you define error_reporting(0), no errors will be shown. If you set error_reporting(E_ALL), all errors will be displayed on the screen.

如果你設定了 error_reporting(0) 的話,將不會有任何錯誤被顯示。如果你設定了 error_reporting(E_ALL),那將會顯示所有的錯誤信息。

以下是一個簡單的范例:

<?php
error_reporting(E_ALL); # 顯示所有的錯誤信息
include('ADOdb-errorhandler.inc.php');
include('ADOdb.inc.php');
include('tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); #不正確的數據表 productsz');
if ($rs) $rs2html($rs);
?>

如果你要把錯誤信息記錄下來,你可以定義兩個選擇性常數 ADODB_ERROR_LOG_TYPE, ADODB_ERROR_LOG_DEST。有關於 ADODB_ERROR_LOG_TYPE 的值,你可以去參考 PHP 使用手冊中有關於 error_log 的說明。在以下的范例中,我使將它設為 3,意思是指將信息記錄到常數 ADODB_ERROR_LOG_DEST 所設定的文件中。

<?php
error_reporting(0); # 不顯示任何的錯誤信息
define('ADODB_ERROR_LOG_TYPE',3);
define('ADODB_ERROR_LOG_DEST','C:/errors.log');
include('ADOdb-errorhandler.inc.php');
include('ADOdb.inc.php');
include('tohtml.inc.php');

$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); ## 不正確的數據表 productsz
if ($rs) $rs2html($rs);
?>

以下則是寫在 error.log 檔的錯誤信息:

(2001-10-28 14:20:38) mysql error: [1146: Table 'northwind.productsz' doesn't exist] in
 EXECUTE("select * from productsz")

第二種錯誤處理方法是 ADOdb-errorpear.inc.php 。使用這種方式,在錯誤發生時會產生 PEAR_Error 衍生物件,而最后產生的 PEAR_Error 物件可以被 ADODB_Pear_Errir() 函數取回。

<?php
include('ADOdb-errorpear.inc.php');
include('ADOdb.inc.php');
include('tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); #不正確的數據表 productsz');
if ($rs) $rs2html($rs);
else {
        $e = ADODB_Pear_Error();
 echo '<p>',$e->message(),'</p>';
}
?>

在引入 ADOdb-errorpear.inc.php 檔之前,藉由定義 ADODB_PEAR_ERROR_CLASS 常數,你可以使用一個 PEAR_Error 衍生類別。為了方便除錯,你可以在 PHP 程序碼的最前面定義預設的錯誤理方式為 PEAR_ERROR_DIE,這將會使得程序一出錯,馬上就輸出錯誤信息,並且停止執行。

include('PEAR.php');
PEAR::setErrorHandling('PEAR_ERROR_DIE');

注意,當錯誤產生時,ADODB並沒有明確的返回一個 PEAR_Error 物件給你。你必需要去調用 ADODB_Pear_Error() 函數去取回最后的錯誤內容。或者,你可以使用 PEAR_ERROR_DIE 這個技巧。

數據集快取

現在,ADODB使用 CacheExecute(),CachePageExecute()及CacheSelectLimit()函數來支持數據集快取。用法類似於沒有快取的函數,除了要加上一個新的參數 $secs2cache。

以下是一個范例 :

include('ADOdb.inc.php'); # 載入ADODB
$ADODB_CACHE_DIR = '/usr/ADODB_cache';
$conn = &ADONewConnection('mysql');  # 建立一個連接
$conn->PConnect('localhost','userid','','agora');# 連接到 MySQL, agora 數據庫
$sql = 'select CustomerName, CustomerID from customers';
$rs = $conn->CacheExecute(15,$sql);

第一個參數是設定查詢的快取秒數。隨后調用的查詢將會使用存放在由  $ADODB_CACHE_DIR 變量指定的快取數據。要強迫查訊執行,並且更新快取記錄,使用 CacheExecute() 函數,並且將第一個參數設為 0 。或者,使用 CacheFlush($sql) 也行。

基於安全的考量,如果你要使用 $ADODB_CACHE_DIR,我們建議你將在 php.ini 里的 register_globals 設成 off。 

在 ADODB 1.80版以后,在 CacheSelectLimit() 及 CacheExecute() 中,參數 secs2cache 是選擇性的。如果你不填上去,系統將會使用 $connection->cacheSecs 屬性的值,它的預設值是 60 分鍾。

       $conn->Connect(...);
        $conn->cacheSecs = 3600*24; // 快取24小時
        $rs = $conn->CacheExecute('select * from table');

參考手冊

以[]包起來的參數為選用參數,可有可無。

共用變量

$ADODB_COUNTRECS

當本變量($ADODB_COUNTRECS)被設為 true 時,如果數據庫驅動程序介面(API)不支持返回被 SELECT 指令所選取的數據筆數,那么 RecordCount() 函數將會自動模擬,並返回正確的數據筆數,預設值即為 true。模擬方式是建立一個內存暫存區來放置這些數據,因此當取回的數據筆數很大時,會占用很大量的內存。當設定本變量值為 false 時,會有最好的效能。本變量在每次執行查訊時都會自動檢查,所以你可以依實際需要在每次查詢前進行設定。

$ADODB_CACHE_DIR

如果你使用了數據集快取功能,那么那些快取數據都會被置放到這個變量所指定的目錄里。所以當你要使用諸如 CacheExecute() 函數前,你應該要先設定好本變量。期於安全的考量,如果你要使用 $ADODB_CACHE_DIR,我們建議你將在 php.ini 里的 register_globals 設成 off。 

$ADODB_FETCH_MODE

這個共用變量決定了數據集以那種方式將數據傳給陣列。數據集在被建立時(如 Execute()或SelectLimit())會把本變量($ADODB_FETCH_MODE)的值保存下來,而隨后本變量($ADODB_FETCH_MODE)的任何改變都不會影響到現存的數據集,只有在以后數據集被建立起來時才會改變。

以下為為已定義的常數:

define('ADODB_FETCH_DEFAULT',0);
define('ADODB_FETCH_NUM',1);
define('ADODB_FETCH_ASSOC',2);
define('ADODB_FETCH_BOTH',3);

以下為一個使用的例子:

 $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 $rs1 = $db->Execute('select * from table');
 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
 $rs2 = $db->Execute('select * from table');
 print_r($rs1->fields); # 顯示 array([0]=>'v0',[1] =>'v1')
 print_r($rs2->fields); # 顯示 array(['col1']=>'v0',['col2'] =>'v1')

在本范例中,如你所見兩個數據集在被Execute()建立時,會依據 $ADODB_FERCH_MODE 的值來決定保存及使用的存取模式。

如果沒有任何的模式被設定,預設值則是 ADODB_FETCH_DEFAULT。呈現的模式則依據數據庫驅動程序而有所不同。為了可攜性,我們建議你固定為 ADODB_FETCH_NUM 及 ADODB_FETCH_ASSOC,因為有許多驅動程序並不支持 ADODB_FETCH_BOTH 。


ADOConnection

提供連接數據庫,執行SQL指令以及一組准格式化的SQL相關函數等功能的物件。

ADOConnection 屬性

databaseType: 要連接的數據庫系統名稱,如 odbc,mssql,mysql┅等。詳細內容請參考上表。

dataProvider: 下層的數據庫結結機制,除了使用 odbc 或 ado 外,一般正常會設為  native

host: 數據庫主機名稱,可用IP或來源名稱(DSN)進行連接。如203.74.225.22 , dbs1.nukepro.com , "localhost" , "odbc_dsn1"

database: 數據庫或連接名稱,如果使用了 ado,則會控制 ado 數據提供驅動程序(ado data provider)。

user: 登入時的 ID,密碼則基於安全考量沒有保留。

raiseErrorFn: 允許你定義一個錯誤處理函數,請參考 ADOdb-errorhandler.inc.php 的范例.

debug: 被設定為 true 時,會顯示除錯信息。

concat_operator: 連接運算元,一般會設為 '+' 或 '||'。這個運算元是為了在 SQL 里連接字串的。會在 Concat 函數中被用到。

fmtDate: 日期格式,在DBDate函數中會使用到,做為送日期數據到數據庫的依據。在Access格式為'#Y-m-d#',在MySQL格式為"/Y-m-d/"。

fmtTimeStamp: 時間格式,在 DBTimeStamp 函數中要送時間數據到數據庫時會使用到。

true: 數據中真值的表現方式,如在Foxpro用'T',MS SQL用'1'。

false: 數據中假值的表現方式,如在Foxpro用'F',MS SQL用'0'。

replaceQuote: 這個字串用來處理逸出符號。例如在 Microsoft SQL 里的雙引號,MySQL里的反斜線符號。主要使用於 qstr 。

autoCommit: 設定是否啟動自動交易模式,預設值為 true。

charSet: 設定使用的字元集,目前只有 interbase 支持。

metaTablesSQL: 使用SQL指令,以返回一份可用的數據表清單。例如在 MySQL 里的 SHOW TABLES。

genID: 如果數據庫有支持的話,這里會存放由GetID()所取得的最后值。

cacheSecs: 快取數據集的秒數。用於當使用者利用 CacheExecute() 或 CacheSeletLimit() 函數,又沒有設定 $secs2cache 參數時的預設值。

sysDate: 利用數據庫函數去取得目前的日期和時間。會使用到原生的日期時間標記格式。


ADOConnection 主要函數

ADOConnection( )

建構函數,請不要直接調用,使用 ADONewConnection() 來代替。

Connect($host,[$user],[$password],[$database])

對服務器或數據來源 $host 非持續性連接,使用者認證代碼為 $user ,密碼為 $password ,如果服務器支持多數據庫,則指定連接到數據庫$database

連接成功返回 true , 失敗則返回 false 。

注意:如果你使用的是 Microsoft ADO,而非 OLEDB,你可以設定 $database 參數為你正在使用的 OLEDB 數據供應器。

PostgreSQL:另一種選擇性的連接方法是將標准的PostgreSQL連接字串放在 $host 參數里,那么其它的參數都會被呼略。

對於 Oracle 及 Oci8,有兩個方法可以連接。第一,使用你定義的區域 tnsnames.ora 里的 TNS 名稱,將這個名稱放在 $database 參數里,然后將 $host 設為 false。另一種方法,設定 $host 為服務器,而 $database 則設成數據庫SID ,這將會不透過 tnsnames.ora 連接。

范例:

 $conn->Connect(false, 'scott', 'tiger', 'name_in_tnsnames'); # 使用 tnsnames.ora
 $conn->Connect('server:1521', 'scott', 'tiger', 'OracleSID'); # 不使用 tnsnames.ora

還有許多的數據庫連接范例在網站 php.weblogs.com/ADOdb 以及在本版所附的 testdatabase.inc.php 文件里。

PConnect($host,[$user],[$password],[$database])

對服務器或數據來源 $host 持續性連接,使用者認證代碼為 $user ,密碼為 $password ,如果服務器支持多數據庫,則指定連接到數據庫$database

連接成功返回 true , 失敗則返回 false 。其它數據請參考 Connect()。

Execute($sql,$inputarr=false)

執行 SQL 指令 $sql ,如果成功,就返回一個對應的 ADORecordSet 物件。要注意的是這個指令如果執行成功時,一定會返回一個數據集,即使是執行 insert 或 update 指令也一樣。

返回對應的 ADORecordSet 物件。例如,如果連接的是 mysql ,那么 ADORecordSet_mysql 將會被返回。當SQL指令執行失敗時會返回 false 值。

$inputarr 參數則用來做為傳入的結合變量。以下是 Oracle 的范例:

 $conn->Execute("SELECT * FROM TABLE WHERE COND=:val", array('val'=> $val));

另一個例子,使用 ODBC ,以 '?' 符號做為協定。

 $conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));

結合變量(Binding variables)
變量的結合可以加速SQL指令編譯及快取的速度,產生較佳的效能。目前只有 Oracle 及 ODBC 支持變量結合。 ODBC 類的 ? 結合在不支持的數據庫里,是以模擬的方式來做到的。

變量結合在 odbc 及 oci8po 驅動程序里的用法。

$rs = $db->Execute('select * from table where val=?', array('10'));

變量結合在 oci8 驅動程序里的用法。

$rs = $db->Execute('select name from table where val=:key',array('key' => 10));

CacheExecute($secs2cache,$sql,$inputarr=false)

類似於 Execute 函數,除了將數據集暫存在 $ADODB_CACHE_DIR 指定的目錄里 $secs2cache 秒外。如果 CacheExecute() 被相同的參數、數據庫、使用者ID及密碼,而且快取也沒有過期,那么快取中的數據集將會被傳回。

 include('ADOdb.inc.php'); 
 include('tohtml.inc.php');
 $ADODB_CACHE_DIR = '/usr/local/ADOdbcache';
 $conn = &ADONewConnection('mysql'); 
 $conn->PConnect('localhost','userid','password','database');
 $rs = $conn->CacheExecute(15, 'select * from table'); # 快取15秒
 rs2html($rs); /* recordset to html table */ 

另外,從ADODB 1.80 版起,$secs2cache 參數成為選擇性(也就是可以不加)

 $conn->Connect(...);
 $conn->cacheSecs = 3600*24; // cache 24 hours
 $rs = $conn->CacheExecute('select * from table');

如果 CacheExecute() 被多次調用,而且數據集也持續在快取中,$secs2cache 參數不會延長被快取的數據集保留時間(因為會被呼略掉),CacheExecute()只能使用在 SELECT 指令上。

效能備注:曾經作了一些效能測試,並且發現這些快取的效益極為顯着。尤其是在數據庫服務器運作效率慢於WEB服務器或數據庫的負荷非常重的時候。ADODB的快取好在它減少了數據庫服務器的負荷。當然,如果你的數據庫服務器負荷不大,而且運作速度也比WEB服務器快,那快取反而會降低效能。

SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)

執行成功會返回一個數據集。完成一個SELECT指令,類似於 PostgreSQL中 SELECT 指令里的LIMIT $numrows OFFSET $offset 宣告。

在 PostgreSQL,SELECT * FROM TABLE LIMIT 3 將會只傳回從頭開始的三筆記錄。相同的,$connection->SelectLimit('SELECT * FROM TABLE',3)也有同樣的意思。

而 SELECT * FROM TABLE LIMIT 3 OFFSET 2 將會返回記錄 3,4及5三筆(也就是在記錄2之后,返回三筆記錄)。相同的,在ADODB里是以 $connection->SelectLimit('SELECT * FROM TABLE',3,2) 來做的。

要注意,LIMIT宣告,在MySQL里是相反位置的。你可以設定 $connection->SelectLimit('select * from table',-1,10) 去取得從第11筆起到最后一筆的記錄。

最后一個參數 $inputarr 是針對支持變量結合功能的數據庫,像 Oracle oci8。這個大大的減少了 SQL 編譯的負荷。底下是 Oracle 范例:

 $conn->SelectLimit("SELECT * FROM TABLE WHERE COND=:val", 100,-1,array('val'=> $val));

oci8po 驅動程序(oracle portable driver)使用更為標准的變量結合:

 $conn->SelectLimit("SELECT * FROM TABLE WHERE COND=?", 100,-1,array('val'=> $val));

Ron Wilson 報告說 SelectLimit 在SQL指令有含 UNION 時會無效,並且建議了針對 mssql 的對策:

> 事實上,我發現一個可以立即最佳化的建構 Select Union 方法。這適用於 MS-SQL,至於
其它數據庫是否適合,就不確定了。當更新求助檔時,你可以參考這個范例。注意,這個方
法不適用於 MySQL。
>
> 改變:
> Select column1 From table1
> Union
> Select column2 From table2
> 
> 成為:
> Select * From (
> Select column1 From table1
> Union
> Select column2 From table2
> )
> As dummytable
> 
> Ron

CacheSelectLimit($secs2cache, $sql, $numrows=-1,$offset=-1,$inputarr=false)

類似於 SelectLimit,除了將數據集暫存在 $ADODB_CACHE_DIR 指定的目錄里 $secs2cache 秒外。

自 1.80版起,$secs2cache成為了選擇性參數:

 $conn->Connect(...);
 $conn->cacheSecs = 3600*24; // 快取24小時
 $rs = $conn->CacheSelectLimit('select * from table',10);

CacheFlush($sql)

更新(刪除)以 $sql 指令存放在 $ADODB_CACHE_DIR 指定目錄內的全部快取數據集。如果你企圖更新所有的快取數據集,請執行如下的PHP指令碼(僅針對 Unix 有效):system("rm -f find ".ADODB_CACH_DIR." -name ADODB_*.cache") ;

ErrorMsg()

返回最后狀態或是錯誤信息。即使沒有錯誤發生,本函數也會返回一個字串。一般情況下,你不需要調用這個函數,除非ADODB函數因為錯誤狀態返回了false值。

注意:如果 debug 旗標被啟動了,SQL 錯誤信息將會在Execute函數被調用時發生錯誤后出現。

ErrorNo()

返回最后的錯誤號碼。注意一點,舊版本的 PHP(4.0.6以前),不支持ODBC的錯誤編號。一般情況下,你不需要調用這個函數,除非ADODB函數因為錯誤狀態返回了false值。

GenID($seqName = 'ADOdbseq',$startID=1)

產生一個順序號碼(在mssql是一個整數值)。對 interbase,mysql,postgresql,oci8,oci8po,ODBC核心類驅動程序(如 access,vfp,db2等等) 都支持。使用 $seqName做為順序名。如果數據庫沒有值,那么GenID()將會自動為你產生一個序號(產生使用者 id 時允許如此),換句話說,你必需自行建立序號。

如果你的數據庫驅動程序要模擬序號,數據表的名稱就是序號名(sequence name),而這個數據表必需有一個字段"id",而其數據類型為整數,或你需要更大些的 numeric(16)。

對於沒有支持序號原生功能的ODBC及數據庫(如 mssql,mysql),我們對每一個序號建立一個數據表。如果序號沒有被預先定義,那啟如的號碼值就設定成 $startID。

注意,mssql驅動程序的 GenID()會產生一個16位元的GUID。自1.90版起,我們將返回整數。

UpdateBlob($table,$column,$val,$where)

允許你以 $where 條件保存一個BLOB(存在 $val里的)值到 $table 里的 $column 字段。

例:

 

 # for oracle
 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, empty_blob())');
 $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');

 # non oracle databases
 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
 $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');

如果成功,會返回 true ,否則返回 false 值。目前有 MySQL, PostgreSQL, Oci8, Oci8po 及 Interbase 支持。其它驅動程序可能有效,仍在持續開發中。

要注意,在PHP 4.1.0 以前的版本,當 Interbase的 blob 值被 SELECT 取回值時,它仍需要被解碼,請使用 $connection->DecodeBlob($blob); 以還原它的內容。

UpdateClob($table,$column,$val,$where)

允許你以 $where 條件保存一個BLOB(存在 $val里的)值到 $table 里的 $column 字段。類似於 UpdateBlog,但主要針對文字大型文件物件。

例:

 

 # for oracle
 $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, empty_clob())');
 $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');

 # non oracle databases
 $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');
 $conn->UpdateBlob('clobtable','clobcol',$clobvalue,'id=1');

UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')

如同 UpdateBlob ,但我們將值改成一個文件路徑,將整個文件存入。

成功返回 true 否則為 false。

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false)

建立一個 SQL 以更新一個被給予的數據集 $rs ,被修改的字段存放在陣列 $arrFields中(這個陣列必需是具名陣列,字段名為索引,值為修正值),會與原來的數據集做一個比較,如果 $forceUpdate被設為 true,那么即使 $arrFields與 $rs->fields完全相同,也會產生出更新的SQL指令。數據集必需在連接狀態。$magicq 被用於指出魔術引號功能是否被啟動。

GetInsertSQL(&$rs, $arrFields,$magicq=false)

建立一個 SQL 以新增一筆記錄到被給予的數據集 $rs。這個查詢必需是在連接狀態。$magicq 被用於指出魔術引號功能是否被啟動。

PageExecute($sql, $nrows, $page, $inputarr=false)

使用數據集的頁碼功能,參數 $page 是以 1 為啟使值,請參考范例 8.

CachePageExecute($secs2cache, $sql, $nrows, $page, $inputarr=false)

使用數據集的頁碼功能,參數 $page 是以 1 為啟使值,請參考范例 8.PageExecute 的快取版。

Close( )

關閉數據庫的連接。PHP4 以數據庫連接結束時不需要特別去清除而享有盛名,因為其參考計數機制會自動幫我們清除掉。

BeginTrans( )

啟始一筆交易。會關閉自動結案功能。執行成功會返回 true 。如果不支持交易功能,部份數據庫會一直傳回 false 值。Interbase,Oracle 及 MSSQL 支持交易機制。請注意,因為 PHP 4.02 版的臭蟲,交易支持在微軟的 ADO 上是無效的。你必需使用你關連式數據庫的原生交易支持功能。當連接結束時,任何開啟的交易都會被還原。

CommitTrans( )

成功的結束一次交易。如果成功,返回 true。如果數據庫並不支持交易功能,那么就只會傳回 true ,以表示數據總是交易成功的。

RollbackTrans( )

結束一次交易,恢復所有改變。執行成功會返回 true 。如果數據庫並不支持交易功能,那么就只會傳回 false ,以表示數據總是不能恢復。

GetOne($sql)

Executes the SQL and returns the first field of the first row as an array. The recordset and remaining rows are discarded for you automatically. If an error occur, false is returned.

執行SQL指令,並且以陣列的方式返回第一筆記錄的第一個字段。數據集及其餘的記錄將會被自動清除,如果發生錯誤,就返回 false 值。

譯者注:這個功能在驗證某筆記錄在不在特別有用,可以減少系統內存及資源的用量。

GetRow($sql)

執行SQL指令,並且以陣列的方式返回第一筆記錄。數據集及其餘的記錄將會被自動清除,如果發生錯誤,就返回 false 值。

Prepare($sql )

預先編譯一個SQL查詢,以便於重覆執行。如果有任何語法錯誤,Prepare()不會顯示任合錯誤,但允許 Execute() 去取得及顯示錯誤。內部實作支持 interbase ,oci8 及選擇性的 ODBC-based 驅動程序。其餘的都是以模擬的方式支持。在模擬的情況下,使用 Prepare() 對效能的增進沒有任何效果。

返回一個包含了原始描述為第一個陣列元素的陣列,其餘的元素內容則視驅動程序而定。如果有錯誤或是模擬方式的 Prepare(),會返回原來的 $sql 字串。那是因為所有的錯誤處理都被集中到 Execute() 里去了。

范例 :

$stmt = $DB->Prepare('insert into table (col1,col2) values (?,?)');
for ($i=0; $i < $max; $i++)
 $DB->Execute($stmt,array((string) rand(), $i));

PrepareSP($sql)

在 mssql 驅動程序里,預編譯預儲程序必需要透過一個特別的函數來調用 mssql_init(),這個動作目前由本函數來處理了。PrepareSP() 可以在所有的驅動程序由被調用,而且以調用 Prepare() 的方式來模擬。使用范例請參考以下的 Parameter() 說明。

和上面的 Prepare() 返回一樣的陣列或 $sql 字串。

Parameter($stmt, $var, $name, $isOutput=false, $maxLen = 4000, $type = false )

在運作中增加一個結合參數。目前相容於 Microsoft SQL 及 Oracle oci8。以下是參數說明:


$stmt  由 Prepare() 或 PrepareSP() 返回的指令。
$var 要結合的 PHP 變量。
$name 要結合的預儲程序的變量名。
[$isOutput] 設定參數傳導的方向,0/false = IN 1=OUT 2= IN/OUT 。 在 oci8 中這個參數會被忽略,因為驅動程序會自動偵測。 
[$maxLen] 參數變量的最大長度。
[$type] 參考 mssql_bind 及 ocibindbyname 在 PHP.NET 的文件說明以取得更多正確值的信息。

在 mssql,$opt 可以被下列的元素所影響:mssql_bind and ocibindbyname 。 例如 ;

# @RETVAL = SP_RUNSOMETHING @myid,@group
$stmt = $db->PrepareSP('SP_RUNSOMETHING'); 
# note that the parameter name does not have @ in front!
$db->Parameter($stmt,$id,'myid'); 
$db->Parameter($stmt,$group,'group',false,64);
# return value in mssql - RETVAL is hard-coded name 
$db->Parameter($stmt,$ret,'RETVAL',true); 
$db->Execute($stmt); 

一個 oci8 的例子:

# 對於 oracle, Prepare 及 PrepareSP 是相同的
$stmt = $db->PrepareSP(
 "declare ret integer;
 begin 
 :RETVAL := SP_RUNSOMETHING(:myid,:group);
 end;");
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
$db->Parameter($stmt,$ret,'RETVAL',true);
$db->Execute($stmt);

請注意,在 oci8 及 mssql 間只有語法上的不同,那是各數據庫實作 SQL 語法問題,ADODB 對於這一部份無能為力。

如果 $type 參數被設定成 false 。在 mssql ,$type 將會動態的由 PHP 變量傳來的類型決定(string => SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 或  float/double=>SQLFLT8),在 oci8,$type 可以被設成 OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) 及 OCI_B_ROWID (ROWID)。如果要傳入空值,使用  $db->Parameter($stmt, $null=null, 'param')。

最后,在 oci8,結合參數可以重覆被使用,而無需再一次調用 PrepareSP() 或 Parameters。但這對 mssql 是不行的。一個 oci8 的范例如下:

$id = 0; $i = 0;
$stmt = $db->PrepareSP( "update table set val=:i where id=:id");
$db->Parameter($stmt,$id,'id');
$db->Parameter($stmt,$i, 'i');
for ($cnt=0; $cnt < 1000; $cnt++) {
 $id = $cnt;
 $i = $cnt * $cnt; # oci8 下可以運作
 $db->Execute($stmt);
}

Bind($stmt, $var, $size=4001, $type=false, $name=false)

這是一個低階函數,只有 oci8 驅動程序支持。只有你確定系統僅支持 Oracle 否則請避免使用它。Parameter() 函數是使用結合變量的另一個建議方式。

Bind() 允許你使用結合變量在你的 sql 敘述中。這里結合一個PHP變量給一個在之前被 Prepare() 預先編譯的 Oracle sql 敘述里定義的名稱。Oracle 以一個冒號為開頭來命名一個變量,而且 ADODB 需要一個被命名的變量去對應 :0,:1,:2,:3,等等。第一次被 Bind() 取得的將會代入 :0,而第二次將會代入 :1,依此類推。對 insert , select 及 update 指令,結合可以提供 100% 的效能提升。

在其餘的參數里,$size 設定數據保存的暫存區大小,$type 是 OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File), OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) 及 OCI_B_ROWID (ROWID) 的類別選項。最后,代替使用預設的 :0,:1 等等名稱,你可以使用 $name 來定義你自己的連接名稱。

接下來的例子展示3個連接變量,使用 p1,p2及p3來結合。這些變量將會配到 :0 , :1 及 :2 。

$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
$DB->Bind($stmt, $p1);
$DB->Bind($stmt, $p2);
$DB->Bind($stmt, $p3);
for ($i = 0; $i < $max; $i++) { 
   $p1 = ?; $p2 = ?; $p3 = ?;
   $DB->Execute($stmt);
}

你也可以使用名稱變量:

$stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:name0, :name1, :name2)");
$DB->Bind($stmt, $p1, "name0");
$DB->Bind($stmt, $p2, "name1");
$DB->Bind($stmt, $p3, "name2");
for ($i = 0; $i < $max; $i++) { 
   $p1 = ?; $p2 = ?; $p3 = ?;
   $DB->Execute($stmt);
}

ADOConnection 公用函數

BlankRecordSet([$queryid])

不再使用,本版已移除。

Concat($s1,$s2,....)

產生一個結合 $s1,$s2,..等 sql 字串的字串,使用了在 concat_operator 字段定義的結合運算符號。如果結合運算符號不被使用,那這個函數將無效,例如 MySQL 。

本函數返回含結合符號的字串。

DBDate($date)

格式化 $date 成數據庫可以接收的格式,這可以是一個 Unix 整數時間記錄格式或是一個 ISO 格式的 Y-m-d。使用 fmtDate 字段所定義的格式。如果傳入的是 null 或是 false 或是 '' ,那將會轉成一個 SQL 的 null。

返回一個日期字串。

DBTimeStamp($ts)

格式化時間記錄格式的 $ts 成數據庫可接受的格式。這可以是一個 Unix 整數時間記錄格式或是一個 ISO 格式的 Y-m-d。使用 fmtDate 字段所定義的格式。如果傳入的是 null 或是 false 或是 '' ,那將會轉成一個 SQL 的 null。

返回一個時間字串。

qstr($s,[$magic_quotes_enabled=false])

將一個字串放在引號內,以送到數據庫中。$magic_quotes_enabled 參數可能看起來很有趣,但這個想法是假設你已經用一個引號來處理了從 POST/GET 變量取來的字串后,然后以 get_magic_quotes_gpc() 做為第二個參數。這會確定這個變量不會被引號處理二次,一次被 qstr 處理,一次被 magic_quotes_gqc

例如:  $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());

返回值是一個被引號處理過的字串。

Affected_Rows( )

返回被SQL指令更新或被刪除掉的數據筆數。如果數據庫不支持,返回一個 false 值。

目前 interbase/firebird 不支持本函數。

Insert_ID( )

返回最后插入時的自動增進值 ID。如果系統不支持,返回 false。

只支持有提供自動增進或物件 ID 的數據庫,目前像是 PostgreSQL, MySQL 以及 MSSQL 都有。PostgreSQL 返回一個 OID,可以在數據庫重載入時改變。只有使用持續連接方式,當你完成一筆交易時,這個函數才會有精確的結果。這是因為被 Execute() 宣告的連接可能和下一個 Execute() 時用的連接不同。

MetaDatabases()

返回一個在服務器中的數據庫清單於陣列里。首先你必需連接到服務器。目前只支持 ODBC, MySQL 及 ADO。

MetaTables()

返回目前數據庫中全部數據表名稱於一個陣列中。如果可能,這個陣列將會排除系統目錄數據表。

MetaColumns($table)

返回一個 ADOFieldObject 的陣列,一個字段物件對應到一個 $table 的所有行。目前 Sybase 不能辨別數據類型,ADO 不能辨識正確的數據類型(所以我們預設為 varchar)..

MetaColumnNames($table)

返回 $table 的行名於一個陣列中。


ADORecordSet(數據集)

當一個SQL指令成功的被 ADOConnection->Execute($sql)執行后,一個 ADORecordSet 物件會被返回回來。這個物件提供了一個虛擬的指標,所以我們可以移動它,從一筆到一筆。也提供一些函數,以取得字段信息和字段類別,並有協助函數去格式化結果,以展示給使用者看。

ADORecordSet 屬性

fields: 包含了目前記錄的陣列。不是關連式陣列,但它的索引值是從 0 到 字段數 - 1。請參考函數 Fields ,這個函數的動作就像是一個關連式陣列。

dataProvider: 連接數據庫的底層機制,正常設定為 native ,除非是使用 odbc 或 ado 。

blobSize: 一個 char , string 或者 varchar object 在被轉成 Blob 前的最大長度(Blob 在顯示時應該使用 textarea)。其它請參考 MetaType 函數。

sql: 保存了建立本數據集所使用的 sql 指令。

canSeek: 如果 Move() 函數有作用,會被設成 true 。

EOF: 當指標被移動到最后一筆時,這個值會被設定成 true 。

ADORecordSet 函數

ADORecordSet( )

建構函數。一般來說你不需要自己調用這個函數。

GetAssoc([$force_array])

如果字段數大於 2 ,那么從數據集中產生一個關連式陣列。這個陣列是從目前的指標起一直到檔尾(EOF)。這個數據集的第一個字段會成為陣列的索引。如果字段數剛好是2,當這陣列被每一個鍵值所建立時,那么索引會直接對應到值,除非  $force_array 被設成 true 。

范例:

以下是我們數據集的數據:

列1: Apple, Fruit, Edible
列2: Cactus, Plant, Inedible
列3: Rose, Flower, Edible

GetAssociation 將會產生一個如下的關聯式陣列:

Apple => [Fruit, Edible]
Cactus => [Plant, Inedible]
Rose => [Flower,Edible]

返回值:

關連式陣列,錯誤則傳回 false 。

GetArray([$number_of_rows])

從目前指標位置產生一個陣列,索引值從 0 到 $number_of_rows - 1 。如果 $number_of_rows 沒有被定義,那會到檔尾(EOF)。

GetRows([$number_of_rows])

是 GetArray() 的同義函數,是為了與 Microsoft ADO 相容才有的。

GetMenu($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])

建立一個 HTML 選單  (<select><option><option></select>) 。數據集的第一欄 (fields[0]) 將會作為 <option> 里的顯示字串。如果數據集有超過一個以上的字段,第二欄 (fields[1]) 將設定成返回給WEB服務器的值(即 value)。選單將被給予 $name 為名稱。

如果 $default_str 被定義了,那么如果 $default_str == fields[0] , 那么這個字段將會被選取。 如果 $blank1stItem 為 true ,那第一個選項將會是空值。$Default_str 在對於可多選清單盒時,可以是一個陣列。

要產生一個選單區,設定 $size 為一個非 0 值(或者傳入 $default_str 為一個陣列)。如果 $multiple_select 為 true ,那么一個選單區將會被產生成有 $size 個項目可見的選單(如果 $size ==  0 那預設為 5 個),而且ADODB將會返回一個陣列給服務器。最后,你可以使用 $moreAttr 去增加其它的屬性,像是 javascript 或樣式表。

選單范例 1: GetMenu('menu1','A',true) 將會產生一個像這樣的選單 : A B C 這里的數據 (A,1), (B,2), (C,3). 請參考 范例 5 。

選單范例 2: 相同的數據, GetMenu('menu1',array('A','B'),false) 將會產生一個 A 及 B 被選取的選單 : A B C

GetMenu2($name, [$default_str=''], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=''])

近似於 GetMenu ,除了 $default_str 將會和 fields[1] 做比對也就是選項值。

選單范 3: 給予在范例 2 里的數據 , GetMenu2('menu1',array('1','2'),false) 將會產生一個選單,A及B將會被選取。然而,這一次的被選取的比對基准是第二個字段,也就是存放要被返回給服務器里的值。

UserDate($str, [$fmt])

轉換日期字串 $str 為另一個格式,UserDate 調用 UnixDate 來解譯 $str ,而 $fmt 預設值是 Y-m-d 。

UserTimeStamp($str, [$fmt])

轉換時間字串 $str 為另一個格式,時間字串格式是 Y-m-d H:i:s , 像是 "2002-02-28 23:00:12"。UserTimeStamp 調用 UnixTimeStamp 來解譯 $str ,而 $fmt 預設值為 Y-m-d H:i:s 。

UnixDate($str)

將日期字串 $str 解譯,並且轉換成 unix mktime 格式(從 1970.01.01 00:00:00 起到現在的秒數)后傳回。預設日期是以 Y-m-d H:i:s 格式來傳入的。而對於 Sybase 及 Microsoft SQL Server 而言 M d Y 也是可以接受的(三個字元的月份表示法是被一個全域陣列所控制的,這個部份可能需要在地化 )。

自 1.91 版起,這個函數存在於 ADORecordSet 及 ADOConnection兩個地方。

UnixTimeStamp($str)

將時間字串 $str 解譯,並且轉換成 unix mktime 格式(從 1970.01.01 00:00:00 起到現在的秒數)后傳回。預設日期是以 Y-m-d H:i:s 格式來傳入的。而對於 Sybase 及 Microsoft SQL Server 而言 M d Y 也是可以接受的(三個字元的月份表示法是被一個全域陣列所控制的,這個部份可能需要在地化 )。

自 1.91 版起,這個函數存在於 ADORecordSet 及 ADOConnection兩個地方。

MoveNext( )

移動內部指標到下一筆,fields 陣列將會自動的更新。如果不能移動,會返回 false 值,其它情況則會返回 true 。

范例 :

$rs = $db->Execute($sql);
if ($rs) 
 while (!$rs->EOF) {
 ProcessArray($rs->fields);
 $rs->MoveNext();
 } 

Move($to)

移動內部指標到指定的列 ($to) 。 列數是零基的,例如,0是第一列。fields 陣列將會自動更新。對於不支持內部卷動的數據庫,ADODB將會自動模擬卷動。部份數據庫不支持向后卷動。對大多數的數據庫言,如果 $to 的位置在 EOF 之后,$to 將會被移動到數據集的最后一筆。有些無名的數據庫使用 odbc 時,可能會沒有動作。

注意:這個函數使用了絕對定址,不像 Microsoft 的 ADO。

返回值是 true 或是 false。如果是 false ,這個內部指標在大多數的實際運作上並沒有移動,所以 AbsolutePosition() 將會返回指標在執行 Move() 之前最后的位置

MoveFirst()

實際上是調用 Move(0) 。注意,有一些數據庫並不支持這個函數。

MoveLast()

實際上是調用 Move(RecordCount() - 1)。注意,有一些數據庫並不支持這個函數。

GetRowAssoc($toUpper=true)

這個函數並不能持續的以理想的方式維持關連陣列的內容(每換一筆記錄,就要重新執行一次)。使用 $ADODB_FETCH_MODE 共用變量來替代它。

返回一個包含了目前記錄的關連式陣列,陣列的索引值就是字段名。字段名全都是大寫的,以便存取。要取得下一筆記錄,你要調用 MoveNext() 。

范例 :
Array ( [ID] => 1 [FIRSTNAME] => Caroline [LASTNAME] => Miranda [CREATED] => 2001-07-05 )

注意:不要同時使用 GetRowAssoc() 和 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC 。因為他們有相同的功能,會彼此交互干擾。

AbsolutePage($page=-1)

返回目前的頁碼,需要先調用 PageExecute() / CachePageExecute() 。參考 Example 8 。

AtFirstPage($status='')

如果在第一頁,返回 true (1基式),需要先調用 PageExecute() / CachePageExecute() 。參考 Example 8 。

AtLastPage($status='')

如果在最后一頁,返回 true (1基式),需要先調用 PageExecute() / CachePageExecute() 。參考 Example 8 。

Fields($colname)

不鼓勵使用,請改以 $ADODB_FETCH_MODE 取代。

當使用原生函數庫時,有些數據庫函數返回具名及索引雙陣列(如 MySQL)。GetRowAssoc() 並不返回結合了具名及索引的陣列元素。

本函數返回由 $colname 所指欄名,在目前記錄里的的字段值。

字段名區分大小寫。

FetchRow()

返回目前記錄內容的陣列,如果是檔尾(EOF),返回 false 。注意:不要把 FetchRow 和 MoveNext() 混用。

用法 :

$rs = $db->Execute($sql);
if ($rs)
 while ($arr = $rs->FetchRow()) {
 # process $arr
 }

FetchInto(&$array)

設定 $array 到目前的記錄里。如果在檔尾(EOF),返回 PEAR_Error 物件。如果成功,返回 1 (DB_OK 常數)。

如果 PEAR 未定義,當 EOF 時返回 false 。FetchRow() 很容易使用,請參考之前的例子。

FetchField($column_number)

返回一個物件,包含了所指字段的名稱,類別及最大長度。如果最大長度不能被明確決定,將會返回 -1 。 行號是以 0 基為計算起點的,請參考 范例 2 。

FieldCount( )

返回數據集里字段數。

RecordCount( )

返回數據集里的記錄筆數。如果無法從數據庫驅動程序API里取得正確的數字,ADODB將會把所有的記錄內容,存放在內存里,等全部取完后,再返回記錄總筆數。這個內存可以藉由設定全域變量 $ADODB_COUNTERECS = false 而被取消(基於執行效能的理由)。當取消后,對某些數據庫,RecordCount() 將會返回 -1 。相關支持狀況,請參考前面的數據庫支持表有詳細的說明。

RowCount 和 RecordCount 是同義函數。

PO_RecordCount($table, $where)

返回在數據集里的記錄筆數。如果數據庫不支持,那么將返回對 $table 數據表下達以 $where 為條件的 SELECT COUNT(*) 指令后返回的值。

$numrows = $rs->PO_RecordCount("articles_table", "group=$group");

會返回數據庫執行 SELECT COUNT(*) FROM articles_table WHERE group=$group 的結果。

FetchObject($toupper=true)

返回目前的記錄為一個物件。如果 $toupper 為 true ,那么物件字段名將會設為大寫。注意:較新的 FetchNextObject() 是取得記錄物件較被建議的方式,請參看后續說明。

FetchNextObject($toupper=true)

取得目前的記錄成一個物件,並且自動移動到下一個記錄。如果在檔尾,返回 false 。如果 $toupper 為 true ,那么物件字段名將會設為大寫。

$rs = $db->Execute('select firstname,lastname from table');
if ($rs) {
 while ($o = $rs->FetchNextObject()) {
 print "$o->FIRSTNAME, $o->LASTNAME<BR>";
 }
}

在使用 FetchNextObject() 時會影響效能,如果效能很重要,你應該使用 fields[] 陣列來存取。

CurrentRow( )

目傳目前數據集的記錄編號,0 表示是第一筆。

AbsolutePosition( )

和 CurrentRow 是相同的函數,是為了和 ADO 相容而存在的。

MetaType($nativeDBType[,$field_max_length],[$fieldobj])

設定資生數據庫里的原生類型 $nativeDBType 為那一種通用數據類型,以及它的最大長度。請注意,如果長度未知,可以設為 -1 。字段物件可以使用 $fieldobj 傳入。這對於像是 mysql 這一類字段物件有較多屬性的數據庫來說,是很有用的。

使用字段 blobsize 及比較 $field_max_length 去決定目前的字段是否為 blob 。

返回值:

  • C:  character 字段,應該使用 <input type="text"> 標記來取值。

  • X: 文字字段(Text) , 長文字字段,使用 <textarea> 標記來顯示數據。

  • B: Blob 字段或者大型的二位元物件(像程序,圖檔等)。

  • D: 日期字段

  • T: 時間字段

  • L: 邏輯字段(真假值)或位元字段

  • N: 數字字段,包含自動進位、編號、整數、浮點數、實數等。

  • I: 整數字段

  • R: 序列字段,包含了序列、自動增進整數,只對被選擇的數據庫作用。

Close( )

關閉目前的數據集。


function rs2html($adorecordset,[$tableheader_attributes], [$col_titles])

這是一個獨立的函數 (rs2heml = recordset to html) ,相當於 PHP 中的 odbc_result_all 函數。本函數會輸出一整個 ADORecordSet,$adorecordset 如同一個 HTML表格。$tableheader_attributes 允許你控制表格里的參數如 cellpadding,cellspacing 及 border 等的屬性。最后,你可以透過 $col_titles 陣列,更換數據庫字段名稱,使用你自己的字段抬頭。這是設計用來快速除錯的機制,不是一個好的表格記錄瀏覽器。

要使用這個函數,你必需引入 tohtml.inc.php 。

rs2html 范例:

<?
include('tohtml.inc.php'); # load code common to ADOdb 
include('ADOdb.inc.php'); # load code common to ADOdb 
$conn = &ADONewConnection('mysql'); # create a connection 
$conn->PConnect('localhost','userid','','agora');# connect to MySQL, agora db
$sql = 'select CustomerName, CustomerID from customers'; 
$rs = $conn->Execute($sql); 
rs2html($rs,'border=2 cellpadding=3',array('Customer Name','Customer ID'));
?>
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM