ADODB手冊

/! 這一篇是ADOdb Database Abstraction Library for PHP (and Python).中譯版本,原作者還沒回應,不過我還是先放上來,如有問題我在拿下!

ADOdb 是PHP的資料庫抽象層的函式庫,目前也有Python的版本;查看 ADOdb for Python docs

PHP 的版本目前支援很多種的資料庫,感謝這個美好的 ADOdb 社群: MySQL、PostgreSQL、 Interbase、 Firebird、 Informix、 Oracle、 MS SQL、 Foxpro、 Access、 ADO、 Sybase、 FrontBase、 DB2、 SAP DB、 SQLite、 Netezza、 LDAP generic ODBC、 ODBTP,Sybase、 Informix、 FrontBase 及 PostgreSQL、 Netezza、 LDAP、 ODBTP 等的驅動是社群的貢獻,這裡有 完整的列表

許多有名的網站應用程式像是 ACIDPostNukeXarayaphpWikiMamboPHP GACLTikiWikieGroupWarephpLens App Server 都使用 ADOdb 作為他們的資料庫抽象層,一些ADOdb受歡迎的原因有:

  • 設計快速,它可能是PHP裡最快的開放原始碼的資料庫抽象層,查看評效
  • 提供相當多的可攜性支援像是日期及型別的處理跟可攜性概要的建構,查看 portable sql tips
  • 支援很多的企業級功能 像是 database backed sessions (session 逾期提醒)、 SQL 碼的產生、樞紐分析表、 所有資料庫的SELECT LIMIT 模擬、效能監控。
  • 容易學習 特別是如果你有Windows的程式設計經驗,你會習慣使用很多的ADO一樣。
  • 很多的 QA Access、 MySQL、 PostgreSQL、 MS SQL、 Oracle 9每個版本都有單位在測試(unit-tested)。
  • 成熟 從2000年八月開始持續的發展中,擁有廣大社群的使用者。
  • 合理的授權期限 (BSD),這意味你可以免付專利費用以及不需詢問作者的許可將它合併入 (甚至是編譯) 你的軟體應用程式,在你的釋出中提供你含括 license.txt,另外這個套件採雙授權 (Lesser GPL)。

PHP 範例程式

include('/path/to/adodb.inc.php');
$DB = NewADOConnection('mysql');
$DB->Connect($server, $user, $pwd, $db);

# M'soft style data retrieval with binds
$rs = $DB->Execute("select * from table where key=?",array($key));
while (!$rs->EOF) {
print_r($rs->fields);
$rs->MoveNext();
}

# PEAR style data retrieval
$rs = $DB->Execute("select * from table where key=123");
while ($array = $rs->FetchRow()) {
print_r($array);
}

# Alternative URI connection syntax:
$DB = NewADOConnection("mysql://$user:$pwd@$server/$db?persist");

# No need for Connect or PConnect when using URI syntax

$ok = $DB->Execute("update atable set aval = 0");
if (!$ok) mylogerr($DB->ErrorMsg());

Other things you can try include:

# Updating tables
$ok = $DB->Execute("update table set col1=? where key=?",array($colval, $key));

# retrieving data shortcuts
$val = $DB->GetOne("select col from table where key='John'");
$row = $DB->GetRow("select col from table where key='John'");
$arr = $DB->GetAll("select col from table");
$arr = $DB->GetAssoc("select key,col from table"); # returns associative array $key=>col

# Retrieve high speed cached recordsets (cached for 3600 secs)
# Cache directory defined in global $ADODB_CACHE_DIR.
# CacheGetOne, CacheRow, CacheGetAll all work

$rs = $DB->CacheExecute(3600, "select orgname from users where user='JOHN'");

還有更多的 連線範例 告訴你如何連接 SQLiteOraclePostgreSQLMicrosoft SQL ServerMS AccessLDAPInterbase/Firebird 等等。

PHP5 支援

ADOdb 已經完全支援 PHP5 ,包括 SPL 及其擴充的支援,舉個例,你可以在PHP5中這樣做:

$rs = $DB->Execute("select * from table");
foreach ($rs as $row) {
print_r($row);
}

假如你含括下列的 adodb-exceptions.inc.php 檔,那麼 ADOdb 在碰到錯誤的時候將會擲出異常處理:

include("/path/to/adodb-exceptions.inc.php");
include("/path/to/adodb.inc.php");
$DB = NewADOConnection('oci8');
$DB->Connect("", "scott", "tiger");
try {
$DB->Execute("select badsql from badtable");
} catch (exception $e) {
print_r($e);
}

PHP 版的下載

Download from SourceForge

需求: PHP 4.1.0 或之後,也可以在 PHP5 使用 (PHP 4.0.5 或 4.0.6 使用 ADOdb 4.61)。

安裝: 解壓縮檔案到一個資料夾,試試上面的範例程式碼,調整一下連接的參數以適合你的資料庫伺服器的使用,並修改sq來配合你的資料表。

偵錯: 設定你連接的除錯屬性,例如 $DB->debug=true; 假如你有問題,它將輸出一堆有用的狀態及錯誤訊息。

ADOdb Lite

ADOdb Lite 是一個不同 PHP 專案是由另一個第三者廠商縮減 ADOdb 函式庫來使用。

Python 版下載

需要 Python 2.3 或之後的版本,可以跟 Psyco配合使用。

從 SourceForge Python ADOdb 文件下載

用ADOdb擴充加速你的PHP程式

Adodb-ext-504.zip 藉著一些C程式碼取代一部份的ADOdb來提供快一倍的加速, ADOdb 會自動偵測使否有安裝此擴充並且會自動使用它,這個擴充相容於 ADOdb 3.32 或之後的版本,及 PHP 4.3.*、 4.4.*、 5.0.* 跟 5.1.*,原始碼有所有的平台而Windows的二進制版本也有包含。

2005/11/26 釋出5.1相容版本。

2005/7/27 釋出4.4相容版本。

2004/11/29 釋出 thread-safe PHP4 及 PHP5 相容版本,並且較少的 dll 相依的需求, PHP 5:測試在 RedHat8 在 WinXP, PHP 4.3.3:測試在 RedHat8、 WinXP 及 Win2000。

PHP 文件

One HTML Page (這是一直在更新的)
Multiple HTML Pages
Windows CHM Format

Python ADOdb Docs

其他PHP版本的文件

Data Dictionary 概要的建構。
Performance Monitoring.
Database-backed Session Management.

MySQL Tutorial
Advanced Oracle Tutorial
Portable SQL Tips with ADOdb
ADOdb Active Record 及資料庫紀錄的OOP封裝。

icarus在DevShed 寫了一些有關ADOdb優秀的文章,新版的文章在 MelonFire:

Part 1 on BasicsPart 2 on Advanced ADOdb, 原來的文章在 DevShed

翻譯

已經有的其他語言的PHP文件:

以及教學:

郵件群組

ADOdb News List: 少量的修改過得郵件群組關於ADOdb的新聞及更新由作者所管理。

ADOdb General ListADOdb未修改過得郵件群組,這個不是由作者所監控。

對於錯誤報告、功能的需求及問題,可以使用 ADOdb Forums,作者有在監控這個論壇。

PHP 的 ADOdb 函式庫手冊

V4.96 Sept 2007 (c) 2000-2007 John Lim (jlim#natsoft.com)

翻譯者:工作達人 ㄚ琪(

感謝 Gyõrvári 'Scr34m' Gábor (scr34m#frontember.hu) 提供 html 分割並轉檔成 chm。

這個軟體採雙授權使用 BSD-Style 及 LGPL,當有任何差異時,BSD-Style 授權會優先採用,這意味你可以使用它在你所有的商業產品中。

有用的ADOdb連結: Download Other Docs

這篇文件涵蓋了ADOdb核心函式,ADOdb有許多其他的模組在其他的文件可以找到:

- Data Dictionary
- Database-backed Sessions
- Database Performance Monitoring.

目錄

簡介

PHP 的資料庫存取函式並不標準,因此產生了一個資料庫類別函式庫可以將不同資料庫的API之間的不同隱藏起來的需求(將差異給封裝起來),這樣我們可以容易地切換資料庫, PHP 4.0.5 或之後的版本是需要的(因為我們有使用 array-based str_replace)。

我們目前支援 MySQL、 Oracle、 Microsoft SQL Server、 Sybase、 Sybase SQL Anywhere、 Informix、 PostgreSQL、 FrontBase、 Interbase (Firebird and Borland variants)、 Foxpro、 Access、 ADO 及 ODBC, 我們也有透過ODBC成功地連接 Progress、 SQLite 及 DB2 等的報告,via ODBC. 我們希望有更多的人可以貢獻驅動來支援其他的資料庫。

PHP4 支援 session 變數,你可以使用ADOdb真的可攜性及規模的彈性來儲存你的 session 資訊,查看 adodb-session.php 有更多的資訊。

另外在撰寫可攜性的SQL時閱讀 http://php.weblogs.com/portable_sql (在釋出的版本中叫 tips_portable_sql.htm ) 這裡的技巧。

ADOdb獨特的功能

  • Windows 的程式設計師容易 接受因為很多的規矩跟Microsoft的ADO相似。
  • 不像其他的PHP資料庫類別,他們的焦點只放在select指令,我們提供了支援的程式來處理新增及更新這樣就可以很快地接受多種的資料庫,提供不同資料庫的日期處理、字串連結及字串標記字元的方法,內建 metatype system 這樣我們可以描述不同的資料庫型別像 CHAR、 TEXT 及 STRING 是相同的。
  • 容易移植 因為所有與資料庫相依的程式碼被都隱藏在後端,所以使用者不再需要去移植類別裡的邏輯。
  • 支援PHP4 session ,查看 adodb-session.php。

人們如何使用 ADOdb

這裡有一些例子說明人們如何使用 ADOdb (更長一點的列表,察看 http://php.weblogs.com/adodb-cool-applications):

  • PhpLens 是一個商業化的資料格元件,它允許酷的網站設計者及好幾天不刮鬍子的程式設計師可以容易地在網路上開發並維護資料庫,這個是由ADOdb的作者在開發。
  • Analysis Console for Intrusion Databases (ACID): 搜尋及處理安全事件的資料庫,以PHP為基礎的分析引擎,資料庫是由安全相關軟體像是 IDSes 及 firewalls (如 Snort, ipchains)等產生,由 Roman Danyliw開發。
  • PostNuke 是很受歡贏得一個免費內容管理系統及網誌系統,它提供完整的 CSS 支援support、 HTML 4.01 transitional 完全承諾、先進的區塊系統及完整得多語言支援。
  • EasyPublish CMS 是另一個免費的內容管理系統,用來在internet、intranet及extranet上管理資訊及整合模組,來自 Norway。
  • NOLA 是有安整得會計、庫存及工作追蹤的應用程式,採用GPL授權,由 Noguska開發。

功能需求及錯誤報告

功能需求及錯誤報告可以 emailed 到 jlim#natsoft.com.my 或張貼文章在 ADOdb Help 論壇: http://phplens.com/lens/lensforum/topics.php?id=4

安裝指南

安裝指南

確定你使用的PHP版本是 4.0.5 版或之後的,解壓縮全部的檔案到你的Web伺服器可以存取的一個目錄裡。

要測試可以修改一些教學範例,確認正確修改了連結參數,你可以使用$db->debug = true來偵錯就像這樣子:

<?php
include('adodb/adodb.inc.php');
$db = ADONewConnection($database);
$db->debug = true;
$db->Connect($server, $user, $password, $database);
$rs = $db->Execute('select * from some_small_table');
print
"<pre>";
print_r($rs->GetRows());
print
"</pre>";
?>

最小安裝

對那些想要釋出ADOdb最小安裝的開發者來說,你需要:

選擇性的:

程式初始化及連結資料庫

程式初始化及連結資料庫

當要執行ADODB時,至少有兩個檔案要被載進來,第一個是 ADOdb.inc.php,這裡面包含了所有資料庫類別中要被使用的函數,對資料庫實作的程式碼則被置放在adodb/driver/adodb-????.inc.php檔案裡。

例如說,要連結一個mysql資料庫:

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

無論何時你需要連結到一個資料庫時,你必需使用ADONewConnection($driver)函數建立一個連結物件,NewADOConnection($driver) 是另一個相同的函數。

當你建立好一個連結物件時,你並沒有真的連結上你的資料庫 (假如你是用dsn這就不再是這樣),首先你需要決定使用永續的或非永續的連結,永續連結的優點就是他們比較快,資料庫的連結不會關掉(即使在你呼叫Close()時),非永續的連結浪費較少的資源,可以降低你的資料庫及web伺服器過載的風險。

要永續連結,使用 $conn->PConnect(), $conn->Connect() 作為非永續連結,有些資料庫也支援 NConnect()的使用可以強迫新連結的建立。

Connection Gotcha: 假如你建立兩個連結,但是使用相同的 userid 及 password,那麼PHP會共享相同的連結,這在連結不同的資料庫時會產生問題,解決的方法是不同的資料庫使用不同的userid,或是使用 NConnect()。

資料來源名稱 (DSN) 支援

自 ADOdb 4.51後你可以透過使用dsn參數給 NewADOConnection (或 ADONewConnection相同的函數)來連結資料庫, dsn 格式是:

	$driver://$username:$password@hostname/$database?options[=value]

NewADOConnection() 會內部呼叫 Connect() 或 PConnect(),假如連結失敗,會傳回false。

	# non-persistent connection
$dsn = 'mysql://root:pwd@localhost/mydb';
$db = NewADOConnection($dsn);
if (!$db) die("Connection failed");

# no need to call connect/pconnect!
$arr = $db->GetArray("select * from table");

# persistent connection
$dsn2 = 'mysql://root:pwd@localhost/mydb?persist';

假如你有特殊字元像是 /:? 在你的dsn裡,那麼你先要 rawurlencode 這個字串:

	$pwd = rawurlencode($pwd);
$dsn = "mysql://root:$pwd@localhost/mydb";
$dsn2 = rawurlencode("sybase_ase")."://user:pass@host/path?query";

合法的選項有:

所有的驅動介面 'persist', 'persistent', 'debug', 'fetchmode'
Interbase/Firebird 'dialect', 'charset', 'buffers', 'role'
M'soft ADO 'charpage'
MySQL 'clientflags'
MySQLi 'port', 'socket', 'clientflags'
Oci8 'nls_date_format', 'charset'

對所有的驅動介面來說,使用選項 persistpersistent 的設定,會強迫使用永續連結, debug 選項允許偵錯,fetchmode 呼叫 SetFetchMode(),假如沒有定義值給選項,那麼這個值會設成1。

ADOdb DSN 跟1.0版的 PEAR DB's DSN 格式相容。

連結資料庫的範例

MySQL 和其他多數的資料庫驅動介面

MySQL 連結是很直接的,他的參數就跟mysql_connect的一樣:

	$conn = &ADONewConnection('mysql'); 
$conn->PConnect('localhost','userid','password','database');

# or dsn
$dsn = 'mysql://user:pwd@localhost/mydb';
$conn = ADONewConnection($dsn); # no need for Connect()

# or persistent dsn
$dsn = 'mysql://user:pwd@localhost/mydb?persist';
$conn = ADONewConnection($dsn); # no need for PConnect()

# a more complex example:
$pwd = urlencode($pwd);
$flags = MYSQL_CLIENT_COMPRESS;
$dsn = "mysql://user:$pwd@localhost/mydb?persist&clientflags=$flags";
$conn = ADONewConnection($dsn); # no need for PConnect()

對大多數的驅動介面來說,你可以使用這標準的函數: Connect($server, $user, $password, $database),或自ADOdb 4.51版後使用 DSN ,除了這以外其他的方式列於下。

PDO

PDO 只在PHP5下用,接受一個特定連結字串的驅動介面:

	$conn =& NewADOConnection('pdo');
$conn->Connect('mysql:host=localhost',$user,$pwd,$mydb);
$conn->Connect('mysql:host=localhost;dbname=mydb',$user,$pwd);
$conn->Connect("mysql:host=localhost;dbname=mydb;username=$user;password=$pwd");

也支援DSN的機制:

	$conn =& NewADOConnection("pdo_mysql://user:pwd@localhost/mydb?persist"); # persist is optional

PostgreSQL

PostgreSQL 7 及 8 使用的連結字串:

a. 標準的連結字串:

	$conn = &ADONewConnection('postgres');
$conn->PConnect('host=localhost port=5432 dbname=mary');

b. 傳統的四個參數:

	$conn->PConnect('localhost','userid','password','database');

c. dsn:

	$dsn = 'postgres://user:pwd@localhost/mydb?persist';  # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect

LDAP

這裡有一個查詢LDAP伺服器的例子,感謝 Josh Eldridge 提供這個介面及範例:

require('/path/to/adodb.inc.php');

/* Make sure to set this BEFORE calling Connect() */
$LDAP_CONNECT_OPTIONS = Array(
Array ("OPTION_NAME"=>LDAP_OPT_DEREF, "OPTION_VALUE"=>2),
Array ("OPTION_NAME"=>LDAP_OPT_SIZELIMIT,"OPTION_VALUE"=>100),
Array ("OPTION_NAME"=>LDAP_OPT_TIMELIMIT,"OPTION_VALUE"=>30),
Array ("OPTION_NAME"=>LDAP_OPT_PROTOCOL_VERSION,"OPTION_VALUE"=>3),
Array ("OPTION_NAME"=>LDAP_OPT_ERROR_NUMBER,"OPTION_VALUE"=>13),
Array ("OPTION_NAME"=>LDAP_OPT_REFERRALS,"OPTION_VALUE"=>FALSE),
Array ("OPTION_NAME"=>LDAP_OPT_RESTART,"OPTION_VALUE"=>FALSE)
);
$host = 'ldap.baylor.edu';
$ldapbase = 'ou=People,o=Baylor University,c=US';

$ldap = NewADOConnection( 'ldap' );
$ldap->Connect( $host, $user_name='', $password='', $ldapbase );

echo "<pre>";

print_r( $ldap->ServerInfo() );
$ldap->SetFetchMode(ADODB_FETCH_ASSOC);
$userName = 'eldridge';
$filter="(|(CN=$userName*)(sn=$userName*)(givenname=$userName*)(uid=$userName*))";

$rs = $ldap->Execute( $filter );
if ($rs)
while ($arr = $rs->FetchRow()) {
print_r($arr);
}

$rs = $ldap->Execute( $filter );
if ($rs)
while (!$rs->EOF) {
print_r($rs->fields);
$rs->MoveNext();
}

print_r( $ldap->GetArray( $filter ) );
print_r( $ldap->GetRow( $filter ) );

$ldap->Close();
echo "</pre>";

使用 DSN:

$dsn = "ldap://ldap.baylor.edu/ou=People,o=Baylor University,c=US";
$db = NewADOConnection($dsn);

Interbase/Firebird

你可以用$host參數定義資料庫:

	$conn = &ADONewConnection('ibase'); 
$conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');

或 dsn:

	$dsn = 'firebird://user:pwd@localhost/mydb?persist&dialect=3';  # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect

SQLite

Sqlite 會在資料庫不存在時建立資料庫。

	$conn = &ADONewConnection('sqlite'); 
$conn->PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist

或 dsn:

	$path = urlencode('c:\path\to\sqlite.db');
$dsn = "sqlite://$path/?persist"; # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect

Oracle (oci8)

使用 oci8,你可以用很多方式連結,注意 oci8 也可以在較新版的Oracle工作,如 9i 及 10g。

a. PHP 跟 Oracle 在同一台機器使用預設的 SID。

	$conn->Connect(false, 'scott', 'tiger');

b. 定義在tnsnames.ora的TNS 服務名稱 (或 ONAMES 或 HOSTNAMES),如 'myTNS'

	$conn->PConnect(false, 'scott', 'tiger', 'myTNS');

 	$conn->PConnect('myTNS', 'scott', 'tiger');

c. 主機位址及 SID

	# with adodb 5.06 or 4.991 and later
$conn->Connect('192.168.0.1', 'scott', 'tiger', "SID=$SID");

# OR with all versions of ADOdb
$conn->connectSID = true;
$conn->Connect('192.168.0.1', 'scott', 'tiger', $SID);

d. 主機位址和服務名稱

	$conn->Connect('192.168.0.1', 'scott', 'tiger', 'servicename');

e. Oracle 連結字串:

	$cstr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$host)(PORT=$port))
(CONNECT_DATA=(SID=$sid)))";
$conn->Connect($cstr, 'scott', 'tiger');

f. ADOdb dsn:

	$dsn = 'oci8://user:pwd@tnsname/?persist';  # persist is optional
$conn = ADONewConnection($dsn); # no need for Connect/PConnect

$dsn = 'oci8://user:pwd@host/sid';
$conn = ADONewConnection($dsn);

$dsn = 'oci8://user:pwd@/'; # oracle on local machine
$conn = ADONewConnection($dsn);

在 PHP 4.3.2、ADOdb 4.54後你也可以在 Oracle 9.2版以後設定 charSet :

	$conn->charSet = 'we8iso8859p1';
$conn->Connect(...);

# or
$dsn = 'oci8://user:pwd@tnsname/?charset=WE8MSWIN1252';
$db = ADONewConnection($dsn);

非DSN的 ODBC (Access、 MSSQL 及 DB2 範例)

ODBC DSN 可以在ODBC控制面板中建立,或者你可以使用非DSN的連結方式,要使用ODBC非DSN的連結你需要 PHP 4.3 或以後的版本。

Microsoft Access:

	$db =& ADONewConnection('access');
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";
$db->Connect($dsn);

Microsoft SQL Server:

	$db =& ADONewConnection('odbc_mssql');
$dsn = "Driver={SQL Server};Server=localhost;Database=northwind;";
$db->Connect($dsn,'userid','password');

或者假如你較喜歡使用 mssql 擴充 (受限於 mssql 6.5 的功能):

	$db =& ADONewConnection('mssql');
$db->Execute("localhost', 'userid', 'password', 'northwind');

DB2:

	$db =& ADONewConnection('db2');
$dsn = "driver={IBM db2 odbc DRIVER};Database=sample;hostname=localhost;port=50000;protocol=TCPIP;".
"uid=root; pwd=secret";
$db->Connect($dsn);

ADO的非DSN連結
假如你使用的PHP版本是4.3.0之前,非DSN連結只能用微軟的 ADO,這是微軟的 COM 基本的API,使用ADOdb函式庫及微軟的ADO範例如下:

<?php
include('adodb.inc.php');
$db = &ADONewConnection("ado_mssql");
print "<h1>Connecting DSN-less $db->databaseType...</h1>";

$myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
. "SERVER=flipper;DATABASE=ai;UID=sa;PWD=;" ;

$db->Connect($myDSN);

$rs = $db->Execute("select * from table");
$arr = $rs->GetArray();
print_r($arr);
?>

高速的 ADOdb

ADOdb 是一個大的類別函式庫,它在效能上 還是打敗 所有其他PHP類別函式庫,這是因為它採用分層的作風設計,像洋蔥那樣,最裡面那層有最快的函數,為了有最好的效率堅持使用下面的函數:

Innermost Layer

Connect, PConnect, NConnect
Execute, CacheExecute
SelectLimit, CacheSelectLimit
MoveNext, Close
qstr, Affected_Rows, Insert_ID

要存取欄位的最快方法就是直接存取$recordset->fields陣列,另外在你連結你的資料庫之前設定全域變數 $ADODB_FETCH_MODE = ADODB_FETCH_NUM,以及 $ADODB_COUNTRECS = false。

假如你的資料庫有支援的話考慮使用繫結的參數,它可以改善查詢計畫的再使用,使用 ADOdb的效能調整系統來快速地確認瓶頸。

安裝 ADOdb C 擴充 可以100%加速 GetAll() 及 GetArray() 效能以及GetAssoc() 30%的效能,它也可以加速oci8 select 敘述30%的效能。

最後確認你有安裝 PHP 加速暫存像是 APC、 Turck MMCache、 Zend Accelerator 或 ionCube。

一些例子:

使用PHP最快的資料存取 使用ADOdb擴充最快的資料存取
$rs =& $rs->Execute($sql);
while (!$rs->EOF) {
var_dump($rs->fields);
$rs->MoveNext();
}
$rs =& $rs->Execute($sql);
$array = adodb_getall($rs);
var_dump($array);


進階提示

假如你有安裝 ADOdb C 擴充 你可以將 $rs->MoveNext() 這個呼叫改為 adodb_movenext($rs),這個倍速這個操作,要馬上擷取整個紀錄集使用 GetArray(),它內部會使用adodb_getall() 這個高速函數。

Execute() 是預設查詢的方式,你可以使用低階的 functions _Execute() 及 _query() 來降低查詢的成本,這兩個函數跟Execute()使用相同的參數。

假如你沒有繫結的參數或者你的資料庫支援繫結 (沒有競賽( emulation)),你可以直接呼叫 _Execute(),略過繫結的競賽(emulation)來呼叫,在_Execute()還是有支援偵錯。

假如你不需要偵錯的設施也不需要競賽(emulated)的繫結,以及不需傳回紀錄集的話你可以呼叫 _query,這對使用 inserts、 updates 及 deletes是很棒的,略過競賽(emulated)競賽、偵錯及紀錄集的處理來呼叫函數,_query()不是傳回 resultid、 true 就是 false。

對於 Informix你可以使用 $db->cursorType = 0來停用可滾動游標(scrollable cursors)。

ADOdb 安全密技

你可能會因自己的目的而想修改 ADOdb,幸運地你可以子類化ADOdb及使用$ADODB_NEWCONNECTION變數來保持向後相容性, $ADODB_NEWCONNECTION 允許你覆載ADONewConnection()的行為, ADOConnection() 檢查這變數並且在它定義時呼叫儲存在這變數的函數名稱。

在下面的例子中,新功能的連結物件放在 hack_mysqlhack_postgres7 類別中,使用$rsPrefix來控制紀錄集類別命名習慣,這裡我們設定為 'hack_rs_',這會使 ADOdb 使用 hack_rs_mysqlhack_rs_postgres7 作為紀錄集類別。

class hack_mysql extends adodb_mysql {
var $rsPrefix = 'hack_rs_';
/* Your mods here */
}

class hack_rs_mysql extends ADORecordSet_mysql {
/* Your mods here */
}

class hack_postgres7 extends adodb_postgres7 {
var $rsPrefix = 'hack_rs_';
/* Your mods here */
}

class hack_rs_postgres7 extends ADORecordSet_postgres7 {
/* Your mods here */
}

$ADODB_NEWCONNECTION = 'hack_factory';

function& hack_factory($driver)
{
if ($driver !== 'mysql' && $driver !== 'postgres7') return false;

$driver = 'hack_'.$driver;
$obj = new $driver();
return $obj;
}

include_once('adodb.inc.php');

不要忘記在你的建構子中呼叫父類別的建構子,假如你想要使用預設的ADOdb 驅動介面讓上面的hack_factory() 函式傳回 false就可以使用。

PHP5 功能

ADOdb 4.02 或以後的版本可明顯地知道你使用的PHP版本,假如偵測到使用PHP5,下面的功能就會啟用:

支援的資料庫

name 下面是你傳給NewADOConnection($name)的值,這樣可以建立那個資料庫的連結。

Name Tested Database RecordCount() usable Prerequisites Operating Systems
access B Microsoft Access/Jet. 需要建立一個 ODBC/DSN。 Y/N ODBC Windows only
ado B

一般未經特別指定的資料庫系統, 透過ADO,允許不設定 DSN連結,使用OLEDB以提供較佳的效能,這是所有ado驅動介面的基本類別。

你可以在連結前設定$db->codePage 。

? 視資料庫而定 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 使用 PHP 特定的db2 擴充有比較好的效能。 Y/N DB2 CLI/ODBC interface

Unix and Windows. Requires IBM DB2 Universal Database client.

odbc_db2 C 使用一般的ODBC擴充來連結DB2。 Y/N DB2 CLI/ODBC interface

Unix and Windows. Unix install hints. I have had reports that the $host and $database params have to be reversed in Connect() when using the CLI interface.

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 方法

你可以在連結前設定 $db->role、 $db->dialect、 $db->buffers 及 $db->charSet。
Y/N Interbase client Unix and Windows
firebird B 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 驅動介面,假如擬是使用Informix 7.3或以後的版本的話使用這一個。 Y/N Informix client Unix and Windows
informix72 C Informix7.3之前的Informix 資料庫不支援SELECT FIRST。 Y/N Informix client Unix and Windows
ldap C LDAP 驅動介面,察看使用範例。 LDAP extension ?
mssql A

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

Y/N Mssql client

Unix and Windows.
Unix install howto and another one.

mssqlpo A

可攜式 mssql 驅動介面,跟上面的mssql驅動介面是一樣的,除了 '||'這個連結操作被轉換成 '+'來使用,. 對於很多其他不同的sql使用||是有很用的移植命令。

Y/N Mssql client

Unix and Windows.
Unix install howto
.

mysql A

MySQL 不支援交易處理,你也可以在連結前設定$db->clientFlags。

Y MySQL client Unix and Windows
mysqli B

支援較新的 PHP5 mysql api。

Y MySQL 4.1+ client Unix and Windows
mysqlt or maxsql A

MySQL 支援交易處理,我們建議使用||作為連結操作會較好移植,這可以這樣執行MySQL:
mysqld --ansi or mysqld --sql-mode=PIPES_AS_CONCAT

Y/N MySQL client Unix and Windows
oci8 A Oracle 8/9. 支援比 oracle 驅動程式還多的功能 (例如: Affected_Rows). 在Connect/PConnect之前,你可能需要先配好環境變數('ORACLE_HOME=...')。

有兩個方式進行連結,用伺服器的IP或服務名稱:
PConnect('serverip:1521','scott','tiger','service')
或使用TNSNAMES.ORA 或 ONAMES 或 HOSTNAMES裡的紀錄:
PConnect(false, 'scott', 'tiger', $oraname).

自2.31以後我們直接支援 Oracle REF 游標變數 (察看 ExecuteCursor)。

Y/N Oracle client Unix and Windows
oci805 C 支援功能較低的 Oracle 8.0.5,SelectLimit 在oic8或oci8po驅動介面是沒有效的。 Y/N Oracle client Unix and Windows
oci8po A

Oracle 8/9 可攜式驅動程式,這跟oci8驅動介面很相近,除了(a)在Prepare()中的bind變數使用?的慣例以取代:bindvar,(b)欄位名稱使用PHP小寫的慣例。

假如從其他的資料庫移植使用這個驅動介面是重要的,不然oci8的驅動介面提供叫好的效能。

Y/N Oracle client Unix and Windows
odbc A 一般的 ODBC,沒有調整的特定資料庫用,要連結使用
PConnect('DSN','user','pwd'),這是所有odbc延伸的驅動介面的逼本類別。
? depends on database ODBC Unix and Windows. Unix hints.
odbc_mssql A 用 ODBC 連接 MSSQL Y/N ODBC Unix and Windows.
odbc_oracle C 用 ODBC 連接 ORACLE Y/N ODBC Unix and Windows.
odbtp B 一般的 odbtp 驅動介面, Odbtp 是一個不同作業系統用來存取Windows ODBC資料來源的軟體。 Y/N odbtp Unix and Windows
odbtp_unicode C 支援unicode的Odtbp
Y/N odbtp Unix and Windows
oracle C 實作舊的 Oracle 7 client API,可以的話使用oci8 驅動介面有較好的效能。 Y/N Oracle client Unix and Windows
netezza C Netezza 驅動介面, Netezza 是依據 postgres 程式碼基礎的。 Y ? ?
pdo C PHP5一般的 PDO 驅動介面。 Y PDO extension and database specific drivers Unix and Windows.
postgres A 一般的 PostgreSQL 驅動介面,目前跟 postgres7 驅動介面一樣。 Y PostgreSQL client Unix and Windows.
postgres64 A PostgreSQL 6.4 及之前的版本使用,不支援 LIMIT。
Y PostgreSQL client Unix and Windows.
postgres7 A 支援LIMIT及其他7版功能的PostgreSQL。 Y PostgreSQL client Unix and Windows.
postgres8 A 跟 postgres7一樣 Y PostgreSQL client Unix and Windows.
sapdb C SAP DB,基於ODBC驅動介面應該運作的不錯。 Y/N SAP ODBC client

?

sqlanywhere C Sybase SQL Anywhere,基於ODBC驅動介面應該運作的不錯。 Y/N SQL Anywhere ODBC client

?

sqlite B SQLite. Y -

Unix and Windows.

sqlitepo B 可攜式 SQLite 驅動介面,這是因為 assoc 模式不能像splite其他的驅動介面一樣運作,換句話說在使用selecting (joining) 多重資料表時,在"sqlite"驅動介面的資料表名稱會被含括在assoc keys 中。

在 "sqlitepo" 驅動介面中,資料表名稱會從傳回的欄位名稱中加調紋,當這個結果有衝突時,會取第一個。

Y -

Unix and Windows.

sybase C Sybase. Y/N Sybase client

Unix and Windows.


"Tested" 欄位說明程式碼被測試及使用的程度。
A = 經過很多人測試及使用的很好
B = 被測試及可用,但有些功能可能尚未實作。
C = 使用者貢獻或實驗階段的驅動介面,可能沒有完全支援最新的ADOdb所有的功能。

"RecordCount() usable"欄位說明 RecordCount() 是否傳回紀錄數目,或是在SELECT敘述執行時傳回-1,假如欄位顯示的是 Y/N 那麼 RecordCount() 就跟預設的全域變數 $ADODB_COUNTRECS=true是一樣的,注意對於龐大紀錄集,關掉RecordCount()的模擬可能會較好,這是因為相當數量的記憶體來作為暫存紀錄集的計算,這個變數會在每次查詢執行時檢查,所以你自由選擇哪一種紀錄集來計算。

教學

Select 指令

任務:連結到 Access 的 Northwind DSN,然後在每一列顯示頭2個欄位。

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

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

 

<?php
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('access'); # create a connection
$conn->PConnect('northwind'); # connect to MS-Access, northwind DSN

$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(); # optional
$conn->Close(); # optional

?>

 

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

$recordSet->fields[]陣列是由PHP資料庫擴充函數庫所產生的。有一些資料庫擴充函數庫僅支援以編號來進行索引,而不支援以欄位名為索引。要強迫使用欄位名索引,也就是要使用關連式陣列,請使用 SetFetchMode 函數當一個資料集被Execute()或是SelectLimit()函數建立時,都會儲存而且使用諸如此類的fetch模式。

$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(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')

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

進階的 Select 指令(使用 Field 物件)

選取一個資料表,顯示最前面的二欄。如果第二欄是一個日期或時間型態欄位,將它格式化成US格式。

<?php
include('adodb.inc.php'); # load code common to ADOdb
$conn = &ADONewConnection('access'); # create a connection
$conn->PConnect('northwind'); # connect to MS-Access, northwind dsn
$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: 欄位的資料原生型別
  • max_length: 欄位的最大長度,部份資料庫像MySQL,並不回傳欄位的正確值,以這個例子而言,就會回傳 -1 。

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

  • C: character 欄位,應該使用 <input type="text"> 標籤來取值。
  • X: TeXt,長文字欄位,使用 <textarea> 標籤來顯示資料
  • B: Blobs欄位或者大型的二位元物件,典型的圖檔。
  • D: 日期欄位
  • T: 時間欄位
  • L: 邏輯欄位(真假值)或位元欄位
  • I: 整數欄位
  • N: 數字欄位,包含自動進位、數值、浮點數、實數以及整數。
  • R: 序列欄位,包含了序列、自動增進整數,只對被選擇的資料庫作用。

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

Inserting

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

<?php
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旗標可以被啟動,以便將錯誤訊息儲存起來。

Debugging

<?php
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=== falseprint 'error inserting';    
?>

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

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

MySQL及選單

連結到MySQL資料庫 agora ,並且從SQL命令中建立一個 <select> 選單,<option>的標題是第一個欄位,回傳值是第二個欄位。

<?php
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');
?>

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

一次連結多個資料庫

<?php
include('adodb.inc.php'); # load code common to ADOdb
$conn1 = &ADONewConnection('mysql'); # create a mysql connection
$conn2 = &ADONewConnection('oracle'); # create a oracle connection

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

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

產生 Update 及 Insert 的SQL指令

注意:從ADOdb 4.56起我們支援 AutoExecute() 提供了GetInsertSQL() 及 GetUpdateSQL() 的進階外覆將事情簡化,例如,一個 INSERT 可以這樣做:

    $record["firstname"] = "Bob"; 
$record["lastname"] = "Smith";
$record["created"] = time();
$insertSQL = $conn->AutoExecute($rs, $record, 'INSERT');

而 UPDATE 可以:

    $record["firstname"] = "Caroline"; 
$record["lastname"] = "Smith"; # Update Caroline's lastname from Miranda to Smith
$insertSQL = $conn->AutoExecute($rs, $record, 'UPDATE', 'id = 1');

原先這一節其他的部份都已過時:

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

以下我們展示如何運用這些函數,我們將存取一個資料表,帶有下列欄位:(ID,FirstName,LastName,Created)。

在這些函數被執行前,你需要藉由一個對資料表的查詢指令(select)來初始化一個資料集。這個想法及程式碼是 Jonathan Younger jyounger#unilab.com設計。

<?php
#==============================================
# 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, testdb
$rs = $conn->Execute($sql); # 執行查詢並取得一個空的紀錄集

$record = array(); # 初始化一個陣列以便存放紀錄資料供新增

# 設定紀錄中的欄位值
$record["firstname"] = "Bob";
$record["lastname"] = "Smith";
$record["created"] = time();

# 傳入空的紀錄集及資料陣列到 insert
# 的 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();
?>

$ADODB_FORCE_TYPE

在轉換的空值的PHP變數到SQL時GetUpdateSQL() 及 GetInsertSQL() 的行為受全域變數$ADODB_FORCE_TYPE控制,可以設成以下的3個值,預設是 ADODB_FORCE_VALUE (3):

0 = 忽略空的欄位,所有陣列中空的欄位都會忽略。
1 = 強迫空值,所有空值、php的null及'null'欄位的字串會變成sql NULL 值。
2 = 強迫空值,所有空值、php的null及'null'欄位的字串會變成sql 空的 '' 或 0 值。
3 = 強迫有值,會被保留,php的null及'null'字串會設成 sql NULL 值及空的欄位 '' 被設成空的'' sql 值。.

define('ADODB_FORCE_IGNORE',0);
define('ADODB_FORCE_NULL',1);
define('ADODB_FORCE_EMPTY',2);
define('ADODB_FORCE_VALUE',3);

感謝 Niko (nuko#mbnet.fi) 對 $ADODB_FORCE_TYPE 程式碼的貢獻。

使用上一筆及下一筆實作捲動

下面的程式碼建立很簡單的資料集傳呼,在這裡你可以將資料集一頁一頁地捲動。

include_once('adodb.inc.php');
include_once(
'adodb-pager.inc.php');
session_start();

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

$pager = new ADODB_Pager($db,$sql);
$pager->Render($rows_per_page=5);

這個程式會建立一個基本的紀錄傳呼看起來像下面這樣:

|< << >> >|

 

 

 

 

 

ID First Name Last Name Date Created
36 Alan Turing Sat 06, Oct 2001
37 Serena Williams Sat 06, Oct 2001
38 Yat Sun Sun Sat 06, Oct 2001
39 Wai Hun See Sat 06, Oct 2001
40 Steven Oey Sat 06, Oct 2001
Page 8/10

一次顯示幾行是由Render($rows) 方法控制,假如你沒有使用任何參數的Render(),ADODB_Pager預設每頁顯示10筆紀錄。

你可以藉著修改你的SQL(大多數的資料庫有支援)來控制欄位的標題:

$sql = 'select id as "ID", firstname as "First Name", lastname as "Last Name", created as "Date Created" from adoxyz';

上面的程式碼可以在這一版的釋出的範例adodb/tests/testpaging.php中找到,而類別ADODB_Pager是在adodb/adodb-pager.inc.php裡頭,ADODB_Pager程式碼適合程式設計師使用,這樣文字連結可以改成影像,而全白背景可以用更多有趣的顏色來取代。

你也可以這樣設定來允許顯示html:

$pager->htmlSpecialChars = false

一些有用的程式碼是Iván Oliva 及 Cornel GSome 貢獻的。

匯出CSV或Exporting in CSV or Tab-分隔的格式

我們提供了一些輔助功能來匯出逗號分隔值(CSV)及Tab-分隔的格式:

<?php
include_once('toexport.inc.php');
include_once(
'adodb.inc.php');

$db = &NewADOConnection('mysql');
$db->Connect($server, $userid, $password, $database);
$rs = $db->Execute('select fname as "First Name", surname as "Surname" from table');

print
"<pre>";
print
rs2csv($rs); # return a string, CSV format
print '<hr>';
$rs->MoveFirst(); # note, some databases do not support MoveFirst
print rs2tab($rs,false); # return a string, tab-delimited false == suppress field names in first line

print '<hr>';
$rs->MoveFirst();
rs2tabout($rs); # send to stdout directly (there is also an rs2csvout function)
print "</pre>";

$rs->MoveFirst();
$fp = fopen($path, "w");
if (
$fp) {
rs2csvfile($rs, $fp); # write to file (there is also an rs2tabfile function)
fclose($fp);
}
?>

歸位符號(Carriage-returns)或換行轉換為空格,欄位名稱會傳回第一行的文字,含有分隔字元的字串會用引用雙引號,雙引號會加上雙引號,這樣可以符合Excel的匯入及匯出的原則。

上面所有的函數使用一個最後的選擇性參數 $addtitles,其預設值是 true,當設成 false 時第一行的欄位名稱會被隱藏。

資料集篩選

Sometimes we want to pre-process all rows in a recordset before we use it. For example, we want to ucwords all text in recordset.

include_once('adodb/rsfilter.inc.php');
include_once(
'adodb/adodb.inc.php');

// ucwords() every element in the recordset
function do_ucwords(&$arr,$rs)
{
foreach(
$arr as $k => $v) {
$arr[$k] = ucwords($v);
}
}

$db = NewADOConnection('mysql');
$db->PConnect('server','user','pwd','db');

$rs = $db->Execute('select ... from table');
$rs = RSFilter($rs,'do_ucwords');
The RSFilter function takes 2 parameters, the recordset, and the name of the filter function. It returns the processed recordset scrolled to the first record. The filter function takes two parameters, the current row as an array, and the recordset object. For future compatibility, you should not use the original recordset object.

智慧的交易

以前做交易的時候你需要使用

$conn
->BeginTrans();
$ok = $conn->Execute($sql);
if (
$ok) $ok = $conn->Execute($sql2);
if (!
$ok) $conn->RollbackTrans();
else
$conn->CommitTrans();

這是很複雜的大計畫因為你必須追蹤錯誤狀態,智慧的交易就較簡單了,你可以呼叫StartTrans()來開始智慧的交易:

$conn
->StartTrans();
$conn->Execute($sql);
$conn->Execute($Sql2);
$conn->CompleteTrans();

CompleteTrans() 在SQL錯誤產生時偵測出來,然後適當的時機會復原/保證(Rollback/Commit),即使在沒有錯誤產生時強迫復原(rollback)使用 FailTrans(),注意復原(rollback)是在 CompleteTrans()完成而不是在 FailTrans()完成。

 

你也可以檢查交易是否失敗,使用 HasFailedTrans(),假如有呼叫FailTrans()或SQL執行時有錯誤會傳回true,確認在你呼叫CompleteTrans()前你有呼叫 HasFailedTrans(),這個只有在StartTrans/CompleteTrans之間使用才能正常運作。

$conn
->StartTrans();
$conn->Execute($sql);
if (!
CheckRecords()) $conn->FailTrans();
$conn->Execute($Sql2);
$conn->CompleteTrans();

最後 StartTrans/CompleteTrans 可以巢狀使用,並且只有最外邊的區塊會執行,跟 BeginTrans/CommitTrans/RollbackTrans 對比來看這不是巢狀的使用。

$conn
->StartTrans();
$conn->Execute($sql);
$conn->StartTrans(); # ignored
if (!CheckRecords()) $conn->FailTrans();
$conn->CompleteTrans(); # ignored
$conn->Execute($Sql2);
$conn->CompleteTrans();

注意:儲存點(Savepoints)現在沒有支援了。

使用自定錯誤處理及 PEAR_Error

ADOdb 支援 PHP5 的例外,只要含括 adodb-exceptions.inc.php ,現在你就能在錯誤發生時捕捉到例外。

	include("../adodb-exceptions.inc.php"); 
include("../adodb.inc.php");
try {
$db = NewADOConnection("oci8://scott:bad-password@mytns/");
} catch (exception $e) {
var_dump($e);
adodb_backtrace($e->gettrace());
}

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

引入了上述檔案後,當發生了下列的錯誤後,將會使得 trigger_error($errorstring,E_USER_ERROR) 被呼叫:
(a) Connect() 或 PConnect() 執行失敗時。
(b) 執行 SQL 指令的函數失敗時,如 Execute() 或 SelectLimit()。
(c) GenID() 進入了無限迴圈時。

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

如果你設定了 error_reporting(0) 的話,將不會有任何錯誤被顯示。如果你設定了 error_reporting(E_ALL),那將會顯示所有的錯誤訊息。你仍然需要使用 ini_set("display_errors", "0" or "1") 來控制錯誤的顯示。

<?php
error_reporting
(E_ALL); # pass any error messages triggered to error handler
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'); #invalid table 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
(E_ALL); # report all errors
ini_set("display_errors", "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")

PEAR_ERROR

第二種錯誤處理方法是 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 物件給你。取而代之的是傳回false,你必需要去呼叫 ADODB_Pear_Error() 函數去取回最後的錯誤內容,或者,你可以使用 PEAR_ERROR_DIE 這個技巧。

錯誤訊息

錯誤訊息可以使用靜態方法ADOConnnection::outp($msg,$newline=true)來輸出,預設它會送訊息到客戶端,你可以覆載這個方法來執行錯誤紀錄。

MetaError 及 MetaErrMsg

假如你在多種資料庫執行下需要錯誤訊息,就用MetaError(),這會傳回一個基於PEAR DB錯誤號碼系統及MetaErrMsg()的虛擬錯誤號碼。

資料來源名稱

我們現在支援使用PEAR樣式的DSN連結,DSN 的連結字串格式如下:

$dsn = "$driver://$username:$password@$hostname/$databasename";

你可以傳 DSN 到靜態類別函數 DB::Connect 或直接給ADONewConnection(),例子如下:

<?php
$username = 'root';
$password = '';
$hostname = 'localhost';
$databasename = 'xphplens';
$driver = 'mysql';
$dsn = "$driver://$username:$password@$hostname/$databasename";;
$db =& ADONewConnection($dsn);
# DB::Connect($dsn); also works if you include 'adodb/adodb-pear.inc.php' at the top
$rs = $db->Execute('select firstname,lastname from adoxyz');
$cnt = 0;
while (
$arr = $rs->FetchRow()) {
print_r($arr); print "<br>";
}
?>

更多資訊及連結範例在 DSN 格式。

樞紐分析表

自 ADOdb 2.30後我們支援新一代的SQL來產生樞紐分析表,也就是我們知道的交叉分析表,為了進一步解釋請閱讀這篇 DevShed Cross-Tabulation 教學,我們假設你的資料庫支援 SQL 表示式。

在這個例子中,我們將使用微軟的 Northwind 資料庫,在資料庫中我們一個產品資料表,我們需要分析這個表的供應商與產品類別,我們會放置供應商在每一列上然後類別放在行上,所以從左邊的資料表,我們產生了右邊的樞紐分析表:

Supplier Category
supplier1 category1
supplier2 category1
supplier2 category2
-->
category1 category2 total
supplier1 1 0 1
supplier2 1 1 2


# Query the main "product" table
# Set the rows to SupplierName
# and the columns to the values of Categories
# and define the joins to link to lookup tables
# "categories" and "suppliers"
#
include "adodb/pivottable.inc.php";
$sql = PivotTableSQL(
$gDB, # adodb connection
'products p ,categories c ,suppliers s', # tables
'SupplierName', # rows (multiple fields allowed)
'CategoryName', # column to pivot on
'p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID' # joins/where
);

上面的程式會產生下面的 SQL:

SELECT SupplierName,
SUM(CASE WHEN CategoryName='Beverages' THEN 1 ELSE 0 END) AS "Beverages",
SUM(CASE WHEN CategoryName='Condiments' THEN 1 ELSE 0 END) AS "Condiments",
SUM(CASE WHEN CategoryName='Confections' THEN 1 ELSE 0 END) AS "Confections",
SUM(CASE WHEN CategoryName='Dairy Products' THEN 1 ELSE 0 END) AS "Dairy Products",
SUM(CASE WHEN CategoryName='Grains/Cereals' THEN 1 ELSE 0 END) AS "Grains/Cereals",
SUM(CASE WHEN CategoryName='Meat/Poultry' THEN 1 ELSE 0 END) AS "Meat/Poultry",
SUM(CASE WHEN CategoryName='Produce' THEN 1 ELSE 0 END) AS "Produce",
SUM(CASE WHEN CategoryName='Seafood' THEN 1 ELSE 0 END) AS "Seafood",
SUM(1) as Total
FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID
GROUP BY SupplierName

你也可以使用範圍來轉換數值欄位及產生加總來處理,這個程式碼在ADODB 2.41 版之後釋出,並且跟之前版本不相容,第二個例子顯示如下:

$sql = PivotTableSQL(
$gDB, # adodb connection
'products p ,categories c ,suppliers s', # tables
'SupplierName', # rows (multiple fields allowed)
array( # column ranges
' 0 ' => 'UnitsInStock <= 0',
"1 to 5" => '0 < UnitsInStock and UnitsInStock <= 5',
"6 to 10" => '5 < UnitsInStock and UnitsInStock <= 10',
"11 to 15" => '10 < UnitsInStock and UnitsInStock <= 15',
"16+" => '15 < UnitsInStock'
),
' p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID', # joins/where
'UnitsInStock', # sum this field
'Sum ' # sum label prefix
);

這會產生:

SELECT SupplierName,
SUM(CASE WHEN UnitsInStock <= 0 THEN UnitsInStock ELSE 0 END) AS "Sum 0 ",
SUM(CASE WHEN 0 < UnitsInStock and UnitsInStock <= 5 THEN UnitsInStock ELSE 0 END) AS "Sum 1 to 5",
SUM(CASE WHEN 5 < UnitsInStock and UnitsInStock <= 10 THEN UnitsInStock ELSE 0 END) AS "Sum 6 to 10",
SUM(CASE WHEN 10 < UnitsInStock and UnitsInStock <= 15 THEN UnitsInStock ELSE 0 END) AS "Sum 11 to 15",
SUM(CASE WHEN 15 < UnitsInStock THEN UnitsInStock ELSE 0 END) AS "Sum 16+",
SUM(UnitsInStock) AS "Sum UnitsInStock",
SUM(1) as Total,
FROM products p ,categories c ,suppliers s WHERE p.CategoryID = c.CategoryID and s.SupplierID= p.SupplierID
GROUP BY SupplierName

資料集快取

現在,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 分鐘。下面兩個是一樣的:

  # (1)
$rs = $db->SelectLimit(30, 'select * from table', 10);

# (2)
$db->cacheSsecs = 30;
$rs = $db->SelectLimit('select * from table', 10);
	$conn->Connect(...);
$conn->cacheSecs = 3600*24; # cache 24 hours
$rs = $conn->CacheExecute('select * from table');

請注意這個 magic_quotes_runtime 應該是關著的,在查詢執行的時候不要改變 $ADODB_FETCH_MODE (或 SetFetchMode) 因為快取的資料集會使用 $ADODB_FETCH_MODE 設定。

MemCache 支援

你也可以在memcache伺服器上分享快取資料集,memcache API 支援一台或多台的池化主機,只有在聯絡不到任一台池化伺服器時連結的錯誤會產生,範例如下:

$db = NewADOConnection($driver);
$db->memCache = true;
$db->memCacheHost = array($ip1, $ip2, $ip3); /// $db->memCacheHost = $ip1; will work too
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)

$db->Connect(...);
$db->CacheExecute($sql);

關於memcache更多資訊可以在 http://www.danga.com/memcached/找到。

Caching API

在4.99/5.05版之後也有一個快取API,有兩個API的實作已經提供檔案及memcache 支援可用。

新的 API 使用2個全域變數來建構自訂的快取類別:

include "/path/to/adodb.inc.php";
$ADODB_CACHE_CLASS = 'MyCacheClass';

class MyCacheClass extends ADODB_Cache_File
{
var $createdir = false; // do not set this to true unless you use temp directories in cache path
function writecache($filename, $contents,$debug=false){...}
function &readcache($filename, &$err, $secs2cache, $rsClass){ ...}
:
}

$DB = NewADOConnection($driver);
$DB->Connect(...); ## MyCacheClass created here and stored in $ADODB_CACHE global variable.

$data = $rs->CacheGetOne($sql); ## MyCacheClass is used here for caching...
>

類別參考手冊

變數

$ADODB_COUNTRECS

當全域變數($ADODB_COUNTRECS)被設為 true 時,如果資料庫驅動程式介面(API)不支援 SELECT 指令所傳回的資料筆數,那麼 RecordCount() 函數將會自動模擬,並傳回資料筆數,預設值即為 true。模擬方式是建立一個記憶體暫存區來放置這些資料,因此當取回的資料筆數很大時,會佔用很大量的記憶體。當設定本變數值為 false 時,會有最好的效能。本變數在每次執行查詢時都會自動檢查,所以你可以選擇那個資料輯要計算筆數。

$ADODB_CACHE_DIR

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

假如你使用 Unix 及 apache,你可能需要設定你的快取目錄的權限類似這樣:

chown -R apache /path/to/adodb/cache
chgrp -R apache /path/to/adodb/cache

$ADODB_LANG

$ADODB_LANG

在MetaErrorMsg()決定使用的語言,預設值是 'en'英語,要找出有哪些支援的語言,可以查看 adodb/lang/adodb-$lang.inc.php的檔案,這裡 $lang 的變數是指支援的語言。

$ADODB_ANSI_PADDING_OFF

要決定是否修剪CHAR欄位的右邊 (ibase/firebird資料庫也可以用在 VARCHAR 欄位),可以設成 true 來修剪,預設是 false,目前可以在 oci8po、ibase 及 firebird 驅動介面下工作,這個功能在 ADOdb 4.01時加入。

$ADODB_FETCH_MODE

$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); # shows array([0]=>'v0',[1] =>'v1')
print_r($rs2->fields); # shows array(['col1']=>'v0',['col2'] =>'v1')

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

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

SetFetchMode 函數

假如你有多個連結物件,並且想要有不同的fetch模式給每個連結,那麼就使用 SetFetchMode, 一旦連結的物件呼叫這個函數,那麼連結物件會忽略全域變數 $ADODB_FETCH_MODE 並且自己會使用內部的 fetchMode 屬性。

$db->SetFetchMode(ADODB_FETCH_NUM);
$rs1 = $db->Execute('select * from table');
$db->SetFetchMode(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')

要取得之前的 fetch 模式,你可以使用檢查 $db->fetchMode 屬性,或使用 SetFetchMode( )的傳回值。

常數

ADODB_ASSOC_CASE

你可以針對某些特定行為不同的驅動介面來控制關聯的取出資料,對於 postgres、 sybase、 oci8po、 mssql、 odbc 及 ibase 驅動介面跟所有衍生自他們的驅動介面, ADODB_ASSOC_CASE 預設產生的資料集他的欄位名稱的key都是小寫的,使用常數 ADODB_ASSOC_CASE 來改變這些關鍵值的設定,有3個可能值:

0 = 關聯小寫欄位名稱。 $rs->fields['orderid']
1 = 關聯大寫欄位名稱。 $rs->fields['ORDERID']
2 = 使用原生的欄位名稱。 $rs->fields['OrderID'] -- 自ADOdb 2.90後這是預設值

要使用這個常數,在你含括adodb.inc.php前宣告它。

define('ADODB_ASSOC_CASE', 2); # use native-case for ADODB_FETCH_ASSOC
include('adodb.inc.php');

ADOConnection

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

執行連結資料庫的物件,執行SQL指令以及一組像是連結及日期格式等的功能函數來產生標準化的SQL指令格式。

  • 連結: Connect PConnect NConnect
  • 執行 SQL: Execute CacheExecute SelectLimit CacheSelectLimit Prepare PrepareSP Parameter GetOne CacheGetOne GetRow CacheGetRow GetAll CacheGetAll GetCol CacheGetCol Replace ExecuteCursor (oci8 only)
  • 產生 SQL: GetUpdateSQL GetInsertSQL
  • Blobs: UpdateBlob UpdateClob UpdateBlobFile BlobEncode BlobDecode
  • 分頁/捲動: PageExecute CachePageExecute
  • 清除: CacheFlush Close
  • 交易: BeginTrans CommitTrans RollbackTrans
  • 擷取資料: SetFetchMode
  • 字串: concat qstr quote
  • 日期: DBDate DBTimeStamp UnixDate UnixTimeStamp OffsetDate SQLDate
  • 列管理: Affected_Rows Insert_ID GenID CreateSequence DropSequence
  • 錯誤處理: ErrorMsg ErrorNo
  • 資料字典 (metadata): MetaDatabases MetaTables MetaColumns MetaColumnNames MetaPrimaryKeys ServerInfo
  • 統計及查詢重整建立: fnExecute 及 fnCacheExecute
  • 不宜使用的: Bind BlankRecordSet

ADOConnection 欄位

databaseType: 要連結的資料庫系統名稱,如 odbc,mssql,mysql…等。

dataProvider: 下層的資料庫連結機制,除了使用 odbcado 外,一般正常會設為  native

host: 資料庫主機名稱,可用IP或來源名稱(DSN)進行連結。

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 支援。

dialect: 設定預設使用的sql方言(dialect),目前只有 interbase 支援這個功能。

metaTablesSQL: 使用SQL指令,以回傳一份可用的資料表清單。例如在 MySQL 裡的 SHOW TABLES。

genID: 如果資料庫有支援的話,這裡會存放由GetID()所取得的最後值。

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

sysDate: 利用資料庫函數去取得目前的日期和時間。對新增及更新有用。

sysTimeStamp:呼叫含有資料庫函數的名稱的字串來取得目前的時間戳記/日期時間值。

leftOuter: 如果知道的話,含有左外連接運算子的字串,不知道時設為false。

rightOuter: 如果知道的話含有左外連接運算子的字串,不知道時設為false。(*我覺得是右外連接吧)

ansiOuter: 如果布林職事真的表示ANSI樣式的右外連接是允許的,例如select * from table1 left join table2 on p1=p2。

connectSID: 布林值表示oci8驅動介面在連結時處理$database參數時用SID,預設為false,這在Oracle 8.0.5及之前的版本有用。

autoRollback: 假如設成真值時 PConnect( ) 這個持續連結可以自動回復,預設是false。

Connection

Connect

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

對伺服器或資料來源 $host 非持續性連結,使用者認證代碼為 $user ,密碼為 $password ,如果伺服器支援多資料庫,則指定連結到資料庫 $database

連結成功回傳 true , 失敗則回傳 false 。

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

PostgreSQL:另一種選擇性的連結方法是將標準的PostgreSQL連結字串放在第一個 $host 參數裡,那麼其它的參數都會被忽略。

對於 Oracle 及 Oci8,有兩個方法可以連結。第一,使用你定義的區域 tnsnames.ora 裡的 TNS 名稱(或叫ONAMES或HOSTNAMES),將這個名稱放在 $database 參數裡,然後將 $host 設為 false。另一種方法,設定 $host 為伺服器,而 $database 則設成資料庫 SID ,這將會不透過 tnsnames.ora 連結。

範例:

# $oraname in tnsnames.ora/ONAMES/HOSTNAMES
$conn->Connect(false, 'scott', 'tiger', $oraname);
$conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora

還有許多的資料庫連結範例在網站 php.weblogs.com/ADOdb 以及在本版所附的 testdatabase.inc.php 檔案裡。

NConnect

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

一直強迫新的連結,對照之下PHP有時會在你使用Connect()或PConnect()時再使用連結,目前只在mysql(PHP 4.3.0或以後的版本)、postgresql 及 oci8-衍生的 驅動介面作用,其他的驅動介面 NConnect() 像 Connect() 的功能。

IsConnected()

假如連結到資料庫傳回 true。

PConnect

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

對伺服器或資料來源 $host 持續性連結,使用者認證代碼為 $user ,密碼為 $password ,如果伺服器支援多資料庫,則指定連結到資料庫 $database

 

自2.21之後我們現在對所選擇的資料庫持續連結時會執行回復的功能,就像PHP手冊建議那樣,查看更新紀錄或原始碼看哪些資料庫有影響。

連結成功回傳 true , 失敗則回傳 false 。其它資料請參考 Connect()。

自 ADOdb 2.21 之後我也支援 autoRollback,假如你這樣設定:

$conn = &NewADOConnection('mysql');
$conn->autoRollback = true; # default is false
$conn->PConnect(...); # rollback here

那麼當使用PConnect()做持續性連結時,ADOdb會先做回復的動作,這是因為在PHP的文件說明PHP不保證當使用持續性連結時交易失敗會回復,這個實作目前在 Oracle、 MySQL、 PgSQL、 MSSQL、 ODBC 有用。

自ADOdb 3.11之後你可以強迫非持續性連結,即使在你呼叫PConnect前有定義常數ADODB_NEVER_PERSIST。

Executing SQL

CacheExecute

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

類似於 Execute 函數,除了將資料集暫存在 $ADODB_CACHE_DIR 指定的目錄裡 $secs2cache 秒以及$inputarr只接受一維陣列外。如果 CacheExecute() 呼叫時有相同的參數$sql、$inputarr、資料庫、使用者userid,而且快取也沒有過期,那麼快取中的資料集將會被傳回。

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'); # cache 15 secs
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');

假如省略了 $secs2cache ,我們可以在$connection->cacheSecs (預設是3600秒或1小時)裡使用這個值,CacheExecute()只有用在SELECT指令中。

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

Execute

Execute($sql,$inputarr=false)

執行 SQL 指令 $sql ,如果成功,就回傳一個對應的 ADORecordSet 衍生類別。要注意的是這個指令如果執行成功時,一定會回傳一個資料集,即使是執行 insert 或 update 指令也一樣,你也可以使用 Prepare() 來準備$sql到指令中。

回傳對應的 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 支援變數繫結。 Interbase/ODBC 類的 ? 繫結在不支援的資料庫裡,是以模擬的方式來做到的。注意假如你使用繫結的話不需要在字串裡用到引號。

變數繫結在 odbc 、interbase 及 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));

批次繫結(Bulk binding)

自ADOdb 3.80以後我們在Excute()支援批次繫結,你可以傳遞一個二維陣列到INSERT/UPDATE或DELETE的指令中。

$arr = array(
array('Ahmad',32),
array('Zulkifli', 24),
array('Rosnah', 21)
);
$ok = $db->Execute('insert into table (name,age) values (?,?)',$arr);

這可以在SQL指令準備時提供很高的效能,這個準備的指令可以重複地執行每一列直到所有列完成或是碰到第一個錯誤,這在匯入資料時很有用。

ExecuteCursor

ExecuteCursor($sql,$cursorName='rs',$parameters=false)

執行一個Oracle的預儲程序,並傳回一個Oracle REF游標變數作為正規的ADOdb資料集,除了oci8外任何其他的資料庫不可以這樣用,感謝 Robert Tuttle 的設計。

$db = ADONewConnection("oci8");
$db->Connect("foo.com:1521", "uid", "pwd", "FOO");
$rs = $db->ExecuteCursor("begin :cursorvar := getdata(:param1); end;",
'cursorvar',
array(
'param1'=>10));
# $rs is now just like any other ADOdb recordset object    rs2html($rs);

ExecuteCursor() 是一個滿有幫助的函數它可以作到下面的事情:

 

	$stmt = $db->Prepare("begin :cursorvar := getdata(:param1); end;", true); 
$db->Parameter($stmt, $cur, 'cursorvar', false, -1, OCI_B_CURSOR);
$rs = $db->Execute($stmt,$bindarr);

ExecuteCursor 只接受一個 out 參數,所以假如你有兩個 out 參數,使用:

	$vv = 'A%';
$stmt = $db->PrepareSP("BEGIN list_tabs(:crsr,:tt); END;");
$db->OutParameter($stmt, $cur, 'crsr', -1, OCI_B_CURSOR);
$db->OutParameter($stmt, $vv, 'tt', 32); # return varchar(32)
$arr = $db->GetArray($stmt);
print_r($arr);
echo " val = $vv"; ## outputs 'TEST'

下面的PL/SQL:

	TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE;

PROCEDURE list_tabs(tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS
BEGIN
OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames;
tablenames := 'TEST';
END list_tabs;

SelectLimit

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

執行成功會回傳一個資料集,否則傳回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 時會無效。

CacheSelectLimit

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

類似於 SelectLimit,除了將回傳的資料集暫存在 $ADODB_CACHE_DIR 指定的目錄裡 $secs2cache 秒外。

自 1.80版起,$secs2cache成為了選擇性參數,你可以在$connection->cacheSecs定義暫存的時間。

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

CacheSelectLimit() 重寫SQL查詢,所以你就不能傳SQL到 CacheFlush,在這個例子裡,要清除CacheSelectLimit()所回傳的暫存SQL資料集,可以設定 $secs2cache 為 -1:

	$db->CacheSelectLimit(-1, $sql, $nrows);

CacheFlush

CacheFlush($sql=false)

更新(刪除)以 $sql 指令存放在 $ADODB_CACHE_DIR 指定目錄內的全部快取資料集。

假如沒有傳入參數,那麼所有的 adodb_*.cache 檔案會刪除。

如果你企圖更新所有的快取資料集,請執行如下的PHP指令碼(僅針對 Unix 有效):

system
("rm -f `find ".$ADODB_CACHE_DIR." -name adodb_*.cache`");

CacheSelectLimit() 重寫SQL查詢,所以你不能傳SQL CacheFlush,在這個例子裡,要清除CacheSelectLimit()傳回的暫存SQL資料集,將 $secs2cache 設為 0:

	$db->CacheSelectLimit(0, $sql, $nrows);

一般要清除所有過期的檔案,你應該在Unix上使用 crontab ,或在Winodws上使用at.exe,以及類似下面的shell腳本:

#------------------------------------------------------
# TRUNCATING OUTPUT FILES OLDER THAN N DAYS
#
# Everything between the 3 lines above and their matching
# lines at the bottom of this section show you how to
# delete any log files whose modification time
# is older than AGED. The AGED variable can be coded in the
# script or passed on the command line.
#------------------------------------------------------
# This particular example deletes files in the TMPPATH
# directory with the string ".cache" in their name that
# are more than 7 days old.
#------------------------------------------------------
AGED=7
find ${TMPPATH} -mtime +$AGED | grep ".cache" | xargs rm -f

Prepare

Prepare($sql )

Prepares (編譯) SQL查詢來重複執行,除了oci8驅動使用傳統的Oracle :varname習慣外,繫結參數用?表示。

傳回的陣列在第一個陣列元素中含有原來的sql指令,其餘的陣列元素則視驅動介面而定,假如有錯誤,或是我們模擬 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(),只支援interbase、oci8及選擇性的ODBC-基礎的驅動介面內,否則它會被模擬,使用模擬的Prepare()沒有效能的優點。

重要:因為PHP的侷限或錯誤,當你使用預存的查詢產生錯誤時,試著在預存前設定 $ADODB_COUNTRECS = false, 這個方式在ODBC會看到。

PrepareSP

PrepareSP($sql,$cursor=false)

在呼叫mssql及oci8(oracle)的預儲程序,以及你可能想繫結傳回值的參數,或是特別的LOB處理時,PrepareSP() 允許你這麼做。

就像Prepare( )回傳相同的陣列或 $sql 字串,假如你不需要繫結傳回值,你應該使用 Prepare( )。

第2個參數,除了oci8之外不會使用到,將它設為true來強迫呼叫 OCINewCursor;這個支援輸出 REF CURSORs。

使用的範例查看 Parameter()。

備註:在 mssql 驅動裡,準備預儲程序需要特別的函數呼叫mssql_init( ), PrepareSP( ) 可以用在所有其他的驅動中,並且以呼叫 Prepare( )來模擬。

Parameter

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

繫結一個PHP變數為輸入到預儲程序變數,參數 $stmt 是PrepareSP()得傳回值,$var 是你想要繫結的 PHP 變數,$name 是預儲程序變數的名稱,選擇性的參數是$maxLen:繫結資料的最大長度,以及$type 值視資料庫而定,查詢php.net有關 mssql_bindocibindbyname 的文件來看$type合法值更多資訊。

InParameter() 是呼叫$isOutput=false時的Parameter()的外覆函數,這個函數的優點是自我文件化,因為 $isOutput 參數不再需要,目前只有 mssql 及 oci8 使用。

這裡有使用oci8的例子:

# For oracle, Prepare and PrepareSP are identical
$stmt = $db->PrepareSP(
"declare RETVAL integer;
begin
:RETVAL :=
SP_RUNSOMETHING(:myid,:group);
end;"
);
$db->InParameter($stmt,$id,'myid');
$db->InParameter($stmt,$group,'group',64);
$db->OutParameter($stmt,$ret,'RETVAL');
$db->Execute($stmt);

使用mssql相同的例子:

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

備註oci8及mssql實作唯一的差異就是 $sql。

假如在mssql裡$type 參數設為 false、$type 會依據傳入的PHP變數型態(string => SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 or 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),要傳null使用$db->Parameter($stmt, $null=null, 'param')

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

要從預儲程序變數繫結PHP變數作為輸出,參數 $stmt 是PrepareSP()傳回值, $var 是你想要繫結的PHP變數,$name 是預儲程序變數的名稱,選擇性的參數$maxLen是繫結資料的最大長度,$type 值視資料庫而定。

OutParameter() 是$isOutput=true時呼叫Parameter()的外覆函數,這個函數的優點是自我文件化紀錄,因為 $isOutput 參數不再需要,目前只有在mssql及oci8使用。

例子可以查看 InParameter

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

這個函數不再推見使用,取代使用的是 InParameter( ) 及 OutParameter( )。

在使用PrepareSP()準備指令後新增一個適合傳回值或特殊資料處理(如 LOBs)的繫結參數,目前只在mssql及oci8使用,這些參數:

$stmt 由 Prepare() 或 PrepareSP() 回傳的指令。
$var 要繫結的 PHP 變數,確定你已經預先初始化!
$name 要繫結的預儲程序的變數名。
[$isOutput] 設定參數傳導的方向,0/false = IN 1=OUT 2= IN/OUT 。 在 oci8 中這個參數會被忽略,因為驅動程式會自動偵測。
[$maxLen] 參數變數的最大長度。
[$type] 參考 mssql_bindocibindbyname 在 PHP.NET 的文件說明以取得更多正確值的資訊。

Param($name )

產生一個相容性的繫結位置符(placeholder),大多數的資料庫的繫結位置符是"?",然而有些資料庫像Oracle使用名稱式的繫結參數,如 ":somevar",這樣允許相容性定義SQL指令的繫結參數:

$sql = 'insert into table (col1,col2) values ('.$DB->Param('a').','.$DB->Param('b').')';
# generates 'insert into table (col1,col2) values (?,?)'
# or 'insert into table (col1,col2) values (:a,:b)
'
$stmt = $DB->Prepare($sql);
$stmt = $DB->Execute($stmt,array('one','two'));

GetOne

GetOne($sql)

新增一個繫結參數的方式要符合 Microsoft SQL Server 及 Oracle oci8的要求,參數是:

執行SQL並且傳回第一列的第一個欄位,資料集及其餘列會自動為你捨棄,假如有錯誤產生,傳回false;使用 ErrorNo() 或 ErrorMsg() 還取得錯誤詳細資料,自從4.96版之後,假如沒有紀錄發現傳回null。

GetAssoc($sql,$inputarr=false,$force_array=false,$first2cols=false)

在給定的查詢$sql以及選擇性的繫結參數$inputarr下傳回關聯性陣列,如果欄位數大於 2 ,那麼從資料集中產生一個關聯式陣列。這個陣列是從目前的指標起一直到檔尾(EOF)。這個資料集的第一個欄位會成為陣列的索引。如果欄位數剛好是2,當這陣列被每一個鍵值所建立時,那麼索引會直接對應到值,除非  $force_array 被設成 true 。

範例:

以下是我們資料集的資料:

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

GetAssoc 會產生下面的2維關聯式陣列:

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

假如資料是:

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

GetAssoc 會產生下列的一維關聯式陣列($force_array==false):

Apple => Fruit
Cactus=>Plant
Rose=>Flower

這個函數傳回:

關聯式陣列,或是錯誤發生時傳回false。

CacheGetAssoc([$secs2cache,] $sql,$inputarr=false,$force_array=false,$first2cols=false)

上面 GetAssoc 函數的快取版本。

CacheGetOne

CacheGetOne([$secs2cache,] $sql)

類似上面的 Get* 函數,除了資料集被序列化並且在$ADODB_CACHE_DIR 資料夾暫存 $secs2cache 秒,這對於少變更資料的查詢可以加速,假如省略了參數,會使用$connection->cacheSecs的值(預設是3600秒或1小時)。

GetRow

GetRow($sql)

執行SQL指令,並且以陣列的方式回傳第一筆記錄。資料集及其餘的記錄將會被自動清除,假如沒有紀錄發現傳回空陣列,如果發生錯誤,就回傳 false 值。

CacheGetRow

CacheGetRow([$secs2cache,] $sql)

類似前面的Get*函數,除了資料集被序列化並在 $ADODB_CACHE_DIR 資料夾暫存$secs2cache秒,在少變更資料時可以加速查詢,注意$secs2cache參數是選擇性的,假如省略的話,會使用$connection->cacheSecs的值(預設是3600秒或1小時)。

GetAll

GetAll($sql,$inputarr=false)

執行SQL並傳回所有紀錄以2維陣列表示,資料集會自動清除,假如有錯誤發生傳回false,GetArrayGetAll同義字。

CacheGetAll

CacheGetAll([$secs2cache,] $sql)

類似前面的Get*函數,除了資料集會序列化以及在$ADODB_CACHE_DIR資料夾暫存$secs2cache秒,在少變更資料時可以加速查詢,注意$secs2cache參數是選擇性的,假如省略的話,使用$connection->cacheSecs的值(預設是3600秒,或1小時)。

GetCol

GetCol($sql)

執行SQL並傳回所有第一行的所有元素用一維陣列表示,資料集會自動清除,假如有錯誤發生,傳回false。

CacheGetCol

CacheGetCol([$secs2cache,] $sql)

類似前面的Get*函數,除了資料集被序列化,並在$ADODB_CACHE_DIR暫存$secs2cache秒,在少變更資料時可以加速查詢,注意$secs2cache參數是選擇性的,假如允許的話我們使用$connection->cacheSecs的值(預設是3600秒或1小時)。

Replace

Replace($table, $arrFields, $keyCols,$autoQuote=false)

嘗試更新一筆紀錄,假如紀錄沒有發現一個插入指令就會產生並執行,失敗時傳回0,如果有更新傳回1,沒有發現紀錄並且新增執行成功傳回2,這跟MySQL的replace刪除紀錄後再新增一筆紀錄不同,這也意旨你不能更新主鍵,唯一的例外是Interbase及其衍生的資料庫,因為Interbase API的一些限制它是使用刪除及新增。

參數$table是資料表名稱,$arrFields是其索引鍵為欄位名稱的關聯式陣列,keyCols是主鍵的名稱,或是如果是複合鍵的話就是欄位名稱的陣列,假如$autoQuote設為true,那麼Replace()會將非數值的值給引號;自動引號不會將空值引號,注意假如你使用SQL函數或運算子不會自動引號。

範例:

# single field primary key
$ret = $db->Replace('atable',
array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'),
'id',$autoquote = true);
# generates UPDATE atable SET firstname='Harun',lastname='Al-Rashid' WHERE id=1000
# or INSERT INTO atable (id,firstname,lastname) VALUES (1000,'Harun','Al-Rashid')

# compound key
$ret = $db->Replace('atable2',
array('firstname'=>'Harun','lastname'=>'Al-Rashid', 'age' => 33, 'birthday' => 'null'),
array('lastname','firstname'),
$autoquote = true);

# no auto-quoting
$ret = $db->Replace('atable2',
array('firstname'=>"'Harun'",'lastname'=>"'Al-Rashid'", 'age' => 'null'),
array('lastname','firstname'));

AutoExecute/GetUpdateSQL

AutoExecute($table, $arrFields, $mode, $where=false, $forceUpdate=true,$magicq=false)

自從ADOdb 4.56版之後,你可以用這個函數在給定的資料表上自動產生及執行INSERT及UPDATE,這個函數是GetInsertSQL()和GetUpdateSQL()的外覆。

AutoExecute() 新增或更新$table要給定一個陣列$arrFields,這個陣列的索引是欄位名稱,陣列值是要儲存的欄位值,注意,在SQL產生前會有一些開銷因為資料表要先查詢來擷取索引資訊,我們產生以$mode為基礎的INSERT或UPDATE(見下面)。

$mode的合法值如下:

  • 'INSERT' 或 1 或 DB_AUTOQUERY_INSERT
  • 'UPDATE' 或 2 或 DB_AUTOQUERY_UPDATE

你必須自己定義常數DB_AUTOQUERY_UPDATE及DB_AUTOQUERY_INSERT或含括adodb-pear.inc.php進來。

假如$mode=='UPDATE'就需要有$where子句,假如$forceUpdate=false那麼我們會先查詢資料庫然後檢查查詢回傳的欄位值比對目前的欄位值;只有在他們不同時才會更新欄位。

成功時傳回true,失敗時傳回false。

使用範例:

$record["firstName"] = "Carol";
$record["lasTname"] = "Smith";
$conn->AutoExecute($table,$record,'INSERT');
# executes "INSERT INTO $table (firstName,lasTname) values ('Carol',Smith')";

$record["firstName"] = "Carol";
$record["lasTname"] = "Jones";
$conn->AutoExecute($table,$record,'UPDATE', "lastname like 'Sm%'");
# executes "UPDATE $table SET firstName='Carol',lasTname='Jones' WHERE lastname like 'Sm%'";

備註:ADOdb的AutoExecute()的強項之一就是只有$table的有效欄位名稱被更新,假如$arrFields含有$table無效欄位名稱的索引,他們會被忽略,在我們這樣做時會有些開銷因為我們必須查詢資料庫來取得欄位名稱,但是你可以不用自己寫SQL指令,你可能比較不在意這個速度,而覺得方便比較好時可以用。

自從4.62後資料表名稱可以在AutoExecute()、GetInsertSQL()或GetUpdateSQL()被呼叫之前藉由設定$rs->tableName來複寫。

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

給定一個資料集$rs及陣列$arrFields要修改的欄位(必須是關聯式陣列有欄位名稱及新值)生成了SQL更新資料表跟目前的資料集比較,假如$forceUpdate是true,那麼我們也要產生SQL即使是$arrFields跟$rs->fields相同,這個資料集需要是關聯的,$magicq被用來指示magic quotes是否啟用(見qstr())。

自從4.52之後,我們允許你傳$force型態參數,而這個會覆寫$ADODB_FORCE_TYPE 全域變數。

自從4.62之後,資料表名稱在AutoExecute()、GetInsertSQL()或GetUpdateSQL()被呼叫前藉著設定$rs->tableName來覆寫。

Generates SQL

GetInsertSQL

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

建立一個 SQL 以新增一筆記錄到被給予的資料集 $rs。這個查詢必需是關聯的。$magicq 被用於指出魔術引號功能是否被啟動(qstr())。

自從2.42之後,你可以傳資料表名稱來代替GetInsertSQL (裡的$rs)的資料集,它會產生一個資料表的新增指令。

自從4.52之後,我們允許你傳$force型態參數,這個會覆寫$ADODB_FORCE_TYPE 全域變數。

自從4.62之後,可以在AutoExecute()、GetInsertSQL()或GetUpdateSQL()被呼叫之前設定$rs->tableName來覆寫資料表名稱。

Blob/Clob Handling

UpdateBlob

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); 以還原它的內容。

就PostgreSQL來說你可以使用blob oid或是bytea攔未來儲存你的blob,你可以使用bytea欄位但不是blob oid來使用UpdateBlob( ),相反地使用 UpdateBlobFile( ) 支援oid但不是bytea資料。

假如你沒有傳oid會使用UpdateBlob()來假定你是用bytea欄位儲存。

假如你沒有任何blob欄位,你可以用$connection->disableBlobs = true來關閉blob處理以改善一般的SQL查詢。

UpdateClob

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

允許你以 $where 條件儲存一個clob(存在 $val裡的)值到 $table 裡的 $column 欄位。類似於 UpdateBlog,但主要針對文字大型檔案物件。
使用:

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

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

UpdateBlobFile

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

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

對PostgreSQL來說假如你使用blob oid就使用這個介面,這個介面不支援bytea欄位。

成功回傳 true 否則為 false。

BlobEncode

BlobEncode($blob)

有些資料庫在上傳前需要blob手動編碼,注意假如你使用UpdateBlob( )或 UpdateBlobFile( ) 會自動轉換,你就不用呼叫這個函數,目前就PostgreSQL說來,BlobEncode()只能用於bytea欄位。

傳回編碼的blob值。

注意有一個連結屬性叫做blobEncodeType,它有3種值:

false - 不需要執行編碼或解碼。
'I' - 需要blob編碼,並且傳回編碼的blob,其值為數值(不需要引號)。
'C' - 需要blob編碼,傳回的blob是字元值(需要引號)。

這純粹是為文件說明,所以接受多資料庫驅動的程式知道在處理blob時要做什麼。

BlobDecode

BlobDecode($blob,$maxblobsize=false)

有需資料庫在做了查詢的指令後需要手動解碼blob,假如資料庫不需要解碼,這個函數會傳回沒有改變的blob,目前BlobDecode只有在PostgreSQL資料庫有需要,也只有在你使用blob oid有用(假如你使用bytea欄位,會自動幫你解碼),預設的maxblobsize可以在$connection->maxblobsize設定,這個設定在adodb4.54版時為256K。

在ADOdb 4.54或之後的版本,blob是傳回的值,在較早的版本blob資料被送到stdout。

$rs = $db->Execute("select bloboid from postgres_table where id=$key");
$blob = $db->BlobDecode( reset($rs->fields) );

Paging/Scrolling

PageExecute

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

使用資料集的頁碼功能,參數 $page 是以 1 為起始值,請參考範例 8.

CachePageExecute

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

使用資料集的頁碼功能,參數 $page 是以 1 為起始值,請參考範例 8,PageExecute 的快取版。

CleanUp

Close

Close( )

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

Transactions

StartTrans, CompleteTrans, FailTrans

StartTrans( )

開始監控交易,在SQL指令執行時,ADOdb會監控SQL錯誤,假如偵測到在CompleteTrans()呼叫時,就可以自動回復。

 

要了解StartTrans()為什麼優先於BeginTrans(),就讓我們使用BeginTrans()來解釋,下列是使用交易的的錯誤方式:

$DB->BeginTrans();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans();

因為你沒有執行錯誤檢查,在更新table1及table2時有可能失敗,這裡有叫好的方式:

$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
if ($ok) $DB->CommitTrans();
else $DB->RollbackTrans();

另一個方式是(自ADOdb 2.0後):

$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if ($ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans($ok);

現在開始頭痛地監控$ok,StartTrans()有很大的改善因為它幫你監控所有的SQL錯誤,假如你的黑箱函數有SQL查詢會執行這會特別有用,而且在StartTrans的區塊內所有的BeginTrans、CommitTrans及RollbackTrans呼叫會被關閉,所以即使黑箱函數做了交易,也會被忽略。

$DB->StartTrans();
CallBlackBox();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CompleteTrans();

注意StartTrans區塊是巢狀的,裡面的區塊會被忽略。

CompleteTrans($autoComplete=true)

關閉StartTrans()的交易呼叫,這個函數監控SQL錯誤,並且沒有錯誤時才會交付,否則會回復,在交付時傳回true,回復時傳回false,假如參數$autoComplete是true在適當情況下監控sql錯誤、交付及回復,設$autoComplete為false時即使沒有偵測到SQL錯誤也會強迫回復。

FailTrans( )

StartTrans()時啟動錯誤的交易,回復只有在CompleteTrans()呼叫時發生。

HasFailedTrans( )

檢查智慧交易是否失敗,例如假如SQL執行失敗傳回true,或是呼叫FailTrans(),假如不是在智慧交易內傳回false。

SetTransactionMode($mode )

SetTransactionMode 可以讓你通過交易模式以用於連結時期下所有隨後的交易,注意:假如你使用mysql或mssql時有持續性連結,你可能想在每頁的請求前明確地重設交易模式,這目前只有在postgresql、mssql、使用InnoDB的及oci8下支援,舉例如下:

$db->SetTransactionMode("SERIALIZABLE");
$db->BeginTrans();
$db->Execute(...); $db->Execute(...);
$db->CommiTrans();

$db->SetTransactionMode(""); // restore to default
$db->StartTrans();
$db->Execute(...); $db->Execute(...);
$db->CompleteTrans();

支援傳入的值有:

  • READ UNCOMMITTED (允許髒讟但是最快)
  • READ COMMITTED (postgres、mssql及oci8預設)
  • REPEATABLE READ (mysql預設)
  • SERIALIZABLE (最慢而且限制最多)

你也可以傳資料庫特定值像是mssql的'SNAPSHOT'或oci8/postgres的'READ ONLY'。

查看PostgreSQLOracle、MySQLMS SQL Server的交易層。

BeginTrans

BeginTrans( )

啟始一筆交易。會關閉自動結案功能。執行成功會回傳 true 。如果不支援交易功能,部份資料庫會一直傳回 false 值。Oracle、PostgreSQL、Interbase、MSSQL、某些版本的MySQL、DB2、Informix、Sybase等等資料庫支援交易機制。當連結結束時,任何開啟的交易都會被還原。

下面是使用交易的錯誤方式:

$DB->BeginTrans();
$DB->Execute("update table1 set val=$val1 where id=$id");
$DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans();

因為你沒有執行錯誤檢查,所以更新table1跟更新table2可能失敗,這裡有較好的方式:

$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if (
$ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
if (
$ok) $DB->CommitTrans();
else
$DB->RollbackTrans();

另一個方式是(自ADOdb 2.0以後):

$DB->BeginTrans();
$ok = $DB->Execute("update table1 set val=$val1 where id=$id");
if (
$ok) $ok = $DB->Execute("update table2 set val=$val2 where id=$id");
$DB->CommitTrans($ok);

明顯地你也可以使用ADOdb錯誤處理死亡並回復你的交易,有些錯誤的資料庫擴充知道會交付所有未解決的交易,所以你可能會在你的錯誤處理中想要明確地做$DB->RollbackTrans()以保安全。

CommitTrans

成功的結束一次交易。如果成功,回傳 true。如果資料庫並不支援交易功能,那麼就只會傳回 true ,以表示資料總是交易成功的。

假如你傳參數$ok=false,這資料會被回復,查看BeginTrans()範例。

RollbackTrans

RollbackTrans($ok=true)

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

SetFetchMode

SetFetchMode($mode)

設定目前連結的擷取模式並將它存在$db->fetchMode,合法的模式有ADODB_FETCH_ASSOC及ADODB_FETCH_NUM,更多資訊見$ADODB_FETCH_MODE

String Manipulation

Concat, IfNull, length, random, substr

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

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

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

IfNull($field, $nullReplacementValue)

可移植的IFNULL函數(Oracle的NVL),對給定的資料庫檢查$field是否為空值並傳回字串的函數,假如是空值,改變值並傳回$nullReplacementValue,例如:

$sql = 'SELECT '.$db->IfNull('name', "'- unknown -'"). ' FROM table';

length

這不是一個函數而是屬性,有些資料庫有"length"而其他的資料庫會以"len"作為函數來測量字串的長度,要使用這個屬性:

  $sql = "SELECT ".$db->length."(field) from table";
$rs = $db->Execute($sql);

random

這不是一個函數而是一個屬性,這個字串會讓sql產生一個介於0.0與1.0之間的一個亂數。

substr

這不是一個函數而是一個屬性,有些資料庫有"substr"而其他的資料庫有"substring"作為函數來擷取一個子字串,要使用這個屬性:

  $sql = "SELECT ".$db->substr."(field, $offset, $length) from table";
$rs = $db->Execute($sql);

對所有的資料庫來說,substr的第一個參數是欄位,第二個是從子字串開頭(以1為基礎)的位移,第3個是子字串的長度。

qstr

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());

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

Quote

Quote($s)

將字串$s引號,適當地轉換資料庫特殊的引號字元,以前會檢查magic quotes 設定,但自從3.31版後為了跟PEAR DB保持相容而停用。

Date Handling

DBDate

DBDate($date)

格式化 $date 成資料庫可以接受的格式,這可以用來傳送日期到資料庫(例如:UPDATE、INSERT或SELECT指令中的where子句),擷取有日期欄位的SELECT指令時使用SQLDate,這$date參數可以是一個 Unix 整數時間記錄格式或是一個 ISO 格式的 Y-m-d。使用 fmtDate 欄位所定義的格式。如果傳入的是 null 或是 false 或是 '' ,那將會轉成一個 SQL 的 null。

回傳一個日期字串。

	$sql = "select * from atable where created > ".$db->DBDate("$year-$month-$day");
$db->Execute($sql);

BindDate($date)

將bind格式中的$date格式化成資料庫可以接受的,一般意思是日期字串不會被引號,不像DBDate會將字串引號。

	$sql = "select * from atable where created > ".$db->Param('0');
// or
$sql = "select * from atable where created > ?";
$db->Execute($sql,array($db->BindDate("$year-$month-$day"));

DBTimeStamp,BindTimeStamp

DBTimeStamp($ts)

格式化時間記錄格式的 $ts 成資料庫可接受的格式。這可以是一個 Unix 整數時間記錄格式或是一個 ISO 格式的 Y-m-d H:i:s。使用fmtTimeStamp欄位所定義的格式。如果傳入的是 null 或是 false 或是 '' ,那將會轉成一個 SQL 的 null。

回傳一個引號的時間字串。

	$sql = "select * from atable where created > ".$db->DBTimeStamp("$year-$month-$day $hr:$min:$secs");
$db->Execute($sql);

BindTimeStamp($ts)

將bind格式中的時間紀錄格式$ts格式化成資料庫可以接受的,一般的意思是時間紀錄格式字串不會加引號,不像DBTimeStamp會將字串加引號。

	$sql = "select * from atable where created > ".$db->Param('0');
// or
$sql = "select * from atable where created > ?";
$db->Execute($sql,array($db->BindTimeStamp("$year-$month-$day $hr:$min:$secs"));

UnixDate

將日期字串 $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

UnixTimeStamp($str)

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

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

OffsetDate

OffsetDate($dayFraction, $basedate=false)

在可移植的作法上允許你以$basedate為基礎來計算未來及過去的日期,假如$basedate沒有定義,就使用目前的日期(午夜12點),在傳給Execute() 時傳回執行計算的SQL字串。

例如在Oracle,要找到從今天算起2.5天後的日期及時間,你可以使用:

# get date one week from now
$fld = $conn->OffsetDate(7); // returns "(trunc(sysdate)+7")

# get date and time that is 60 hours from current date and time
$fld = $conn->OffsetDate(2.5, $conn->sysTimeStamp); // returns "(sysdate+2.5)"

$conn->Execute("UPDATE TABLE SET dodate=$fld WHERE ID=$id");

這個函數可以在mysql、mssql、oracle、oci8及postgresql2.13版後的驅動介面下使用,在其他的驅動介面提供給他們允許日期做數值運算也可以使用。

SQLDate

SQLDate($dateFormat, $basedate=false)

傳回一個含有原生SQL函數來將日期或日期欄位$basedate格式化的字串,這在SELECT指令中擷取日期欄位時使用,要送日期到資料庫(例如:在UPDATE、INSERT或SELECT指令的where子句)使用DBDate( ),它使用$dateFormat字串,這個字串支援:

 Y: 4-digit Year
Q: Quarter (1-4)
M: Month (Jan-Dec)
m: Month (01-12)
d: Day (01-31)
H: Hour (00-23)
h: Hour (1-12)
i: Minute (00-59)
s: Second (00-60)
w: day of week (0-6 or 1-7 depending on DB)
l: day of week (as string - lowercase L)
W: week in year (0..53 for MySQL, 1..53 for PostgreSQL and Oracle)
A: AM/PM indicator

所有其他的字元當字串處理,你也可以使用跳脫字元,可選擇使用的資料庫包括mysql、postgresql、mssql、oci8及DB2。

這在寫有日期的GROUP BY的可移植sql指令很有用,例如要顯示以季來區分銷售物品的總費用(日期被存在一個叫postdate的欄位):

$sqlfn = $db->SQLDate('Y-QQ','postdate'); # get sql that formats postdate to output 2002-Q1
$sql = "SELECT $sqlfn,SUM(cogs) FROM table GROUP BY $sqlfn ORDER BY 1 desc";

Row Management

Affected_Rows

Affected_Rows( )

回傳被SQL指令更新或被刪除掉的資料筆數。如果資料庫不支援,回傳一個 false 值。

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

Insert_ID and RowLock

Insert_ID( )

回傳最後插入時的自動增進值 ID。如果系統不支援,回傳 false。

只支援有提供自動增進或物件 ID 的資料庫,目前像是 PostgreSQL、MySQL 以及 MSSQL 都有。PostgreSQL 回傳一個 OID,可以在資料庫重載入時改變。

RowLock($table,$where)

交易的期間鎖住一個資料表列,舉例在table1鎖住紀錄$id:

	$DB->StartTrans();
$DB->RowLock("table1","rowid=$id");
$DB->Execute($sql1);
$DB->Execute($sql2);
$DB->CompleteTrans();

db2、interbase、informix、mssql、oci8、postgres、sybase有支援。

Sequences

GenID

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版起,我們將回傳整數。

CreateSequence

CreateSequence($seqName = 'adodbseq',$startID=1)

產生序列,下一次GenID( )會被呼叫,傳回值會是$startID,這是在2.60版時加入的。

DropSequenceD

DropSequence($seqName = 'adodbseq')

刪除序列,2.60版時加入。

Error Handling

ErrorMsg

ErrorMsg()

回傳最後狀態或是錯誤訊息,錯誤訊息會在Execute()呼叫時重新設定。

即使沒有錯誤發生,本函數也會回傳一個字串。一般情況下,你不需要呼叫這個函數,除非ADODB函數因為錯誤狀態回傳了false值。

注意:如果 debug 旗標被啟動了,SQL 錯誤訊息將會在Execute函數被呼叫時發生錯誤後出現。

IgnoreErrors($saveErrHandlers=false)

允許你忽略錯誤,這樣子StartTrans()/CompleteTrans()不會被影響,而且在有錯物發生時也沒有預設的錯誤處理被呼叫,這在你想要檢查一個欄位或資料表是否存在於一個資料庫中時不會出現不存在的錯誤是很有用的。

使用:

$saveErrHandlers = $conn->IgnoreErrors();
$rs = $conn->Execute("select field from some_table_that_might_not_exist");
$conn->IgnoreErrors($saveErrHandlers);

警告:不要在使用IgnoreErrors()程式碼區塊內呼叫StartTrans()/CompleteTrans()。

ErrorNo

ErrorNo()

回傳最後的錯誤號碼,錯誤號碼會在每次呼叫Execute()後重新設定,假如傳回0就是沒有錯誤發生。

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

MetaError($errno=false)

依據PEAR DB的錯誤號碼系統回傳一個虛擬錯誤號碼,在你呼叫這個函數前需要含括adodb-error.inc.php,參數$errno是你想要轉換的原生錯誤號碼,假如你沒有傳任何參數,MetaError會呼叫ErrorNo()並且轉換它,假如錯誤號碼沒有被虛擬,MetaError會傳回-1(DB_ERROR)。

MetaErrorMsg($errno)

MetaError()傳回對等文字錯誤訊息的錯誤號碼。

ErrorMsg()

回傳最後狀態或是錯誤訊息,這個錯誤訊息每次在Execute()呼叫後重新設定

即使沒有錯誤發生,本函數也會回傳一個字串。一般情況下,你不需要呼叫這個函數,除非ADODB函數因為錯誤狀態回傳了false值。

注意:如果 debug 旗標被啟動了,SQL 錯誤訊息將會在Execute函數被呼叫時發生錯誤後出現。

Data Dictionary

MetaDatabases

MetaDatabases()

回傳一個在伺服器中的資料庫清單於陣列裡。首先你必需連結到伺服器。目前只支援 ODBC、MySQL 及 ADO。

MetaTables

MetaTables($ttype=false, $showSchema=false)

回傳目前資料庫中全部資料表及檢視名稱於一個陣列中。如果可能,這個陣列將會排除系統目錄資料表。要只顯示資料表使用$db->MetaTables('TABLES'),要只顯示檢視使用$db->MetaTables('VIEWS'),$showSchema參數目前只在DB2使用,在設成true時會新增綱要名稱到資料表,例如,"SCHEMA.TABLE"。

MetaColumns

MetaColumns($table, $notcasesensitive=true)

回傳一個 ADOFieldObject 的陣列,一個欄位物件對應到一個 $table 的所有行。一個欄位物件是一個有(name, type, max_length) 定義的類別實體,目前 Sybase 不能辨別資料型別,ADO 不能辨識正確的資料型別(所以我們預設為 varchar)。

$notcasesensitive 參數決定我們是否要將資料表名稱變成大寫或小寫來使其合乎標準(有些資料庫需要),這個在MySQL ISAM資料表無法運作。

支援綱要的,可以傳$table參數,"$schema.$tablename",這只有在選擇的資料庫才有支援。

MetaColumnNames

MetaColumnNames($table)

回傳 $table 的行名於一個陣列中。自ADOdb4.22以後使用關聯式陣列,其索引用大寫表示。

例如:array('FIELD1' => 'Field1', 'FIELD2'=>'Field2')

MetaPrimaryKeys

MetaPrimaryKeys($table)

傳回一個含有$table主鍵的欄位名稱的陣列,目前支援的有mysql、odbc(含括db2、odbc_mssql等等)、mssql、postgres、interbase/firebird、oci8。

檢視(及一些資料表)有主鍵但有時候這個資訊無法從資料庫得知,你可以定義一個函數ADODB_View_PrimaryKeys($databaseType, $database, $view, $owner)這會傳回一個含有主鍵欄位的陣列,假如這個函數存在,它可以在MetaPrimaryKeys()找不到資料表或檢視的主鍵時呼叫。

// In this example: dbtype = 'oci8', $db = 'mydb', $view = 'dataView', $owner = false 
function ADODB_View_PrimaryKeys($dbtype,$db,$view,$owner)
{
switch(strtoupper($view)) {
case 'DATAVIEW': return array('DATAID');
default: return false;
}
}

$db = NewADOConnection('oci8');
$db->Connect('localhost','root','','mydb');
$db->MetaPrimaryKeys('dataView');

MetaForeignKeys($table, $owner=false, $upper=false)

傳回一個外鍵的關聯式陣列,假如不支援傳回false,例如假如資料表employee有一個外鍵employee.deptkey指向dept_table.deptid,和employee.posn=posn_table.postionid 且 employee.poscategory=posn_table.category,那麼$conn->MetaForeignKeys('employee') 會傳回

	array(
'dept_table' => array('deptkey=deptid'),
'posn_table' => array('posn=positionid','poscategory=category')
)

這個選擇性的綱要或擁有者可以定義在$owner,假如$upper是true,那麼資料表名稱(陣列索引)使用大寫。

ServerInfo

ServerInfo()

傳回一個含有'description'跟'version'元素的陣列,這個'description'元素含有資料庫的描述字串,'version'則是版本號碼(也是字串)。

Statistics and Query Rewriting

LogSQL 方法, fnExecute 及 fnCacheExecute 屬性

LogSQL($enable=true)

呼叫這個函數來安裝SQL登錄及定時函數(使用fnExecute),然後所有的SQL指令會紀錄在資料庫的一個adodb_logsql資料表,假如adodb_logsql資料不存在,而你又有適當的權限時ADOdb會產生資料表,這裡有選擇資料庫的DDL範例:

 

		mysql:
CREATE TABLE adodb_logsql (
created datetime NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 text NOT NULL,
params text NOT NULL,
tracer text NOT NULL,
timer decimal(16,6) NOT NULL
)

postgres:
CREATE TABLE adodb_logsql (
created timestamp NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 text NOT NULL,
params text NOT NULL,
tracer text NOT NULL,
timer decimal(16,6) NOT NULL
)

mssql:
CREATE TABLE adodb_logsql (
created datetime NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 varchar(4000) NOT NULL,
params varchar(3000) NOT NULL,
tracer varchar(500) NOT NULL,
timer decimal(16,6) NOT NULL
)

oci8:
CREATE TABLE adodb_logsql (
created date NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 varchar(4000) NOT NULL,
params varchar(4000),
tracer varchar(4000),
timer decimal(16,6) NOT NULL
)

使用:

	$conn->LogSQL(); // turn on logging
:
$conn->Execute(...);
:
$conn->LogSQL(false); // turn off logging

# output summary of SQL logging results
$perf = NewPerfMonitor($conn);
echo $perf->SuspiciousSQL();
echo $perf->ExpensiveSQL();

紀錄的一個限制是回復也會避免SQL被紀錄。

自ADOdb 3.91後,另外查看Performance Monitor

fnExecute 及 fnCacheExecute 屬性

這兩個屬性允許你定義ADOdb處理所有的sql指令的瓶頸函數,這可以允許你執行統計分析及sql查詢的重寫,例如,要計算所有的快取查詢及非快取查詢,你可以這樣做:

# $db is the connection object
function &CountExecs($db, $sql, $inputarray)
{
global $EXECS;

if (!is_array(inputarray)) $EXECS++;
# handle 2-dimensional input arrays
else if (is_array(reset($inputarray))) $EXECS += sizeof($inputarray);
else $EXECS++;

$null = null;
return $null;
}

# $db is the connection object
function CountCachedExecs($db, $secs2cache, $sql, $inputarray)
{
global $CACHED; $CACHED++;
}

$db = NewADOConnection('mysql');
$db->Connect(...);
$db->fnExecute = 'CountExecs';
$db->fnCacheExecute = 'CountCachedExecs';
:
:
# After many sql statements:`
printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$CACHED, $CACHED);

fnExecute函數會在sql被解析及執行前被呼叫,所以你可以執行一個查詢重寫,假如你可以傳一個預儲指令,那麼$sql就是一個陣列 (見Prepare),fnCacheExecute函數只有在資料集被快取時呼叫,這個函數參數分別比對Execute及CacheExecute函數,除了$this (連結物件)被當作第一個參數傳遞外。

自ADOdb 3.91後fnExecute的行為視其定義函數的傳回值而定,假如不傳回值$sql會在這之前執行,這對查詢重寫或計算sql的查詢很有用。

但是你可能想替換Execute函數成你自己設計的,假如是這樣子那麼你的函數就要回傳值,如果有值回傳,這個值可以立即回傳,就可以不用任何處理,這用在ADOdb內執行LogSQL()函數。

不適用的

Bind

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

這是一個低階函數,只有 oci8 驅動程式支援。只有你確定系統僅支援 Oracle 否則請避免使用它。

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);
}
You can also use named variables:

$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);
}

BlankRecordSet

不再使用,自1.99版後移除。

ADORecordSet

ADORecordSet

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

  • 傳回一列:FetchRow FetchInto FetchObject FetchNextObject FetchObj FetchNextObj
  • 傳回所有列:GetArray GetRows GetAssoc
  • 捲動:Move MoveNext MoveFirst MoveLast AbsolutePosition CurrentRow AtFirstPage AtLastPage AbsolutePage
  • 選單產生:GetMenu GetMenu2
  • 日期:UserDate UserTimeStamp UnixDate UnixTimeStamp
  • 資料集資訊:RecordCount PO_RecordSet NextRecordSet
  • 欄位資訊:FieldCount FetchField MetaType
  • 清除:Close
  • 不適用:GetRowAssoc Fields

ADORecordSet( )

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

ADORecordSet 屬性

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

dataProvider: 連結資料庫的底層機制,正常設定為 native ,除非是使用 odbcado

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

sql: 儲存了建立本資料集所使用的 sql 指令。

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

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

傳回一列

FetchRow

FetchRow()

回傳目前記錄內容的陣列,如果是檔尾(EOF),回傳 false 。FetchRow( )在內部傳回目前列後移動到夏衣筆紀錄。

注意:不要把FetchRow()和 MoveNext() 混用。

使用:

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

FetchInto

FetchInto(&$array)

設定 $array 到目前的記錄裡。如果在檔尾(EOF),回傳 PEAR_Error 物件。如果成功,回傳 1 (DB_OK 常數),假如PEAR沒有定義,在EOF時回傳false,FetchInto( )在內部傳回目前列之後移動到下一筆紀錄。

FetchRow() 很容易使用,請參考之前的例子。

FetchObject

FetchObject($toupper=true)

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

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[] 陣列來存取。FetchObj()傳回物件型態的目前紀錄,不像FetchObject欄位名不會轉成大寫。

FetchObj

FetchObj()

回傳目前的記錄為一個物件,不像 FetchObject欄位名稱不會被設為大寫

FetchNextObj

FetchNextObj()

取得目前的記錄成一個物件,不像FetchObject欄位名稱不會設為大寫。

Returns all rows

GetArray

GetArray([$number_of_rows])

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

GetRows

GetRows([$number_of_rows])

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

GetAssoc

GetAssoc([$force_array])

從資料集中回傳一個關連式陣列,如果欄位數大於 2 ,那麼從資料集中回傳一個2維陣列,這個資料集的第一個欄位會成為陣列的索引。如果欄位數剛好是2,會產生一個一維陣列,索引會直接對應到值(除非  $force_array 被設成 true,陣列針對每個值產生) 。

範例:

以下是我們資料集的資料:

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

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

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

回傳值:

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

Scrolling

Move

Move($to)

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

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

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

MoveNext

MoveNext( )

移動內部指標到下一筆,fields 陣列將會自動的更新。如果不能移動,會回傳 false 值,其它情況則會回傳 true ,假如傳回false,$this->fields也會設成false。

範例:

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

MoveFirst

MoveFirst()

實際上是呼叫 Move(0) 。注意,有一些資料庫並不支援這個函數。

MoveLast

MoveLast()

實際上是呼叫 Move(RecordCount() - 1)。注意,有一些資料庫並不支援這個函數。

AbsolutePosition

AbsolutePosition( )

CurrentRow 是相同的函數,是為了和 ADO 相容而存在的,傳回資料集的目前列,0是第一列。

AtFirstPage

AtFirstPage($status='')

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

AtLastPage

AtLastPage($status='')

如果在最後一頁,回傳 true (1基式),需要先呼叫 PageExecute() / CachePageExecute() 。參考Example 8

AbsolutePage

AbsolutePage($page=-1)

回傳目前的頁碼,需要先呼叫 PageExecute() / CachePageExecute() ,參考Example 8

選單產生

GetMenu

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

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將會被選取。然而,這一次的被選取的比對基準是第二個欄位,也就是存放要被回傳給伺服器裡的值。

Dates

UserDate

UserDate($str, [$fmt])

轉換日期字串 $str 為另一個格式,日期格式是Y-m-d或Unix時間紀錄格式,$fmt 預設值是 Y-m-d 。

UserTimeStamp

UserTimeStamp($str, [$fmt])

轉換時間字串 $str 為另一個格式,時間字串格式是 Y-m-d H:i:s,像是 "2002-02-28 23:00:12"或Unix時間字串格式。UserTimeStamp 呼叫 UnixTimeStamp 來解譯 $str ,而 $fmt如果沒有定義的話預設值為 Y-m-d H:i:s。

Recordset info

RecordCount

RecordCount( )

回傳資料集裡的記錄筆數。如果無法從資料庫驅動程式API裡取得紀錄筆數,ADOdb將會把所有的記錄內容,存放在記憶體裡,等全部取完後,再回傳記錄總筆數。這個記憶體可以藉由設定全域變數 $ADODB_COUNTERECS = false 而被取消(基於執行效能的理由)。當取消後,對某些資料庫,RecordCount() 將會回傳 -1 。相關支援狀況,請參考前面的資料庫支援表有詳細的說明。

RowCount 和 RecordCount 是同義函數。

PO_RecordCount

PO_RecordCount($table, $where)

回傳在資料集裡的記錄筆數。如果資料庫不支援,那麼將回傳對 $table 資料表下達以 $where 為條件的 SELECT COUNT(*) 指令後回傳的值。

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

NextRecordSet

針對允許多重資料集的資料庫用一個查詢回傳,這個函數允許你切換到下一個資料集,目前只有在mssql驅動介面支援。

$rs = $db->Execute('execute return_multiple_rs');
$arr1 = $rs->GetArray();
$rs->NextRecordSet();
$arr2 = $rs->GetArray();

Field info

FieldCount

FieldCount( )

回傳資料集裡欄位數。

FetchField

FetchField($column_number)

回傳一個物件,包含了所指欄位的名稱,類別及最大長度。如果最大長度不能被明確決定,將會回傳 -1 。 行號是以 0 基為計算起點的。

MetaType

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

根據資料庫欄位裡的原生型別 $nativeDBType 字串及欄位$field_max_length長度來決定是哪一種通用資料型別,請注意,如果長度未知,可以設field_max_length為 -1 。FetchField()傳回的欄位物件可以使用 $fieldobj 或第一個參數$nativeDBType傳入。這對於像是 mysql 這一類欄位物件有較多屬性像是 primary_key的資料庫來說,是很有用的。

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

例如$db->MetaType('char')回傳'C'。
回傳值:

  • C: character 欄位,應該使用 <input type="text"> 標記來取值。
  • X: clob(大型字元物件)或長文字欄位,使用 <textarea> 標記來顯示資料。
  • D: 日期欄位
  • T: 時間欄位
  • L: 邏輯欄位(真假值)或位元欄位
  • N: 數字欄位,包含十進位、數值、整數、浮點數、實數等。
  • I: 整數欄位
  • R 序列欄位,包含了序列、自動增進整數,必須是數值。
  • B: Blob 欄位或者大型的二位元物件(像程式,圖檔等)。

自ADOdb 3.0後MetaType接受$fieldobj作為第一個參數來取代$nativeDBType。

Cleanup

Close

Close( )

關閉目前的資料集,清除所有記憶體及與資料集關聯的資源。

假如記憶體管理不是問題的話,你不需要在PHP程式碼最後資料集關閉時呼叫這個函數,SQL指令像是INSERT/UPDATE/DELETE不會回傳資料集,所以像這樣的SQL指令你不必呼叫Close()。

不適用的

GetRowAssoc

GetRowAssoc($toUpper=true)

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

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

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

Fields

本函數回傳由 $colname 所指欄名,在目前記錄裡的的欄位值,欄位名稱沒有大小寫分別。

這是一個方便函數,要較高的效能使用$ADODB_FETCH_MODE

rs2html

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 範例:

<?php
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'));
?>

資料庫驅動指南

這一節說明如何建構一個類別來連結一個新的資料庫,為了確認沒有重工,假如你決建構這樣的一個類別請先寄mail給我jlim#natsoft.com.my。

首先要決定呼叫資料庫型別的小寫名稱,讓我們說是呼叫xbase。

然後我們需要在檔案adodb-xbase.inc.php裡建構兩個類別ADODB_xbase及ADORecordSet_xbase。

資料庫驅動最簡單的格式是現存ODBC驅動的調適版本,然後我們只需要建構類別ADODB_xbase繼承自ADODB_odbc來支援新的datetimestamp格式,使用的concatenation 運算子,truefalse,對於ADORecordSet_xbase繼承自ADORecordSet_odbc我們需要改變MetaType函數,查看adodb-vfp.inc.php這個範例。

更複雜的是一個全新的資料庫驅動,這個驅動是連結一個新的PHP擴充,這樣你將需要實作幾個函數,幸運地你不需修改大部份複雜的程式碼,你只需要複寫一些殘餘的(stub)函數,查看adodb-mysql.inc.php 這個範例。

ADOdb內部使用的預設日期格式是YYYY-MM-DD (Ansi-92),所有的日期應該在傳入ADOdb日期函數前被轉成這樣的格式,見Oracle這個如何使用ALTER SESSION來改變在_pconnect _connect裡預設的日期格式的範例。

複寫ADOConnection函數

定義你的ADOConnection衍生函數是選擇性的,不需要呼叫這個基本的類別建構子。

_connect:Connect的低階實作,回傳true或false,應該設定_connectionID。

_pconnect:PConnect的低階實作,回傳true或false,應該設定_connectionID。

_query:執行查詢,回傳queryID或false。

_close:關閉連結 -- PHP 應該清除所有的資料集。

ErrorMsg: 以私有變數 _errorMsg儲存錯誤訊息。

要設定的ADOConnection欄位

_bindInputArray: 假如SQL的新增及修改允許使用 ?像ODBC這樣的繫結參數時設成true。

fmtDate

fmtTimeStamp

true

false

concat_operator

replaceQuote

hasLimit 支援<ySQL的SELECT * FROM TABLE LIMIT 10。

hasTop 支援Microsoft樣式的SELECT TOP 10 * FROM TABLE。

要覆寫的ADORecordSet函數

你將定義你的ADORecordSet衍生類別的建構子來呼叫父類別建構子。

FetchField: 前面ADORecordSet的說明文件有提到

_initrs:資料集的低階初始化:設定_numOfRows及_numOfFields欄位-- 建構子所呼叫。

_seek:前往一個特定列,不會載入資料到欄位陣列中,這可以用_fetch來做,回傳true或false,注意有些像是Interbase不支援seek的實作,要設canSeek為false。

_fetch: 使用資料庫的擴充函數來擷取一列然後移到下一列,設定欄位陣列,假如參數$ignore_fields是true那麼不需要產生這個欄位陣列,只是移到下一列,然後傳回true或false。

_close:關閉資料集。

Fields: 假如PHP擴充傳回的陣列不是關聯式,你必須覆寫這一個,參考adodb-odbc.inc.php這個範例,像MySQL及MSSQL這樣的資料庫可以傳回關聯式陣列,不需要覆寫這個函數。

要設定的ADOConnection欄位

canSeek:假如_seek函數可以運作的話設成true。

待辦事項

見RoadMap這篇文章。

另外可以參考ADOdb proxy這篇文章關於使用http遠端程序呼叫來繫結Windows及Unix的資料庫,為了教學,參考palslib.com關於資料庫的資訊,以及閱讀這篇Optimizing PHP文章。

變動紀錄

4.990/5.05 11 Jul 2008

 

新增mysqli的多重資料集支援"Geisel Sierote" geisel#4up.com.br. 見http://phplens.com/lens/lensforum/msgs.php?id=15917

Malcolm Cook 新增新的Reload()函數來啟動紀錄,見http://phplens.com/lens/lensforum/msgs.php?id=17474

Thanks Zoltan Monori [monzol#fotoprizma.hu] 修正iterator、SelectLimit、GetRandRow等等的錯誤

在嚴重負載下,oci8的效能監控會關閉Ixora檢視

修正sybase驅動SQLDate來使用str_replace(),另外對於adodb5變更sybase驅動UnixDate及UnixTimeStam呼叫

變更oci8 lob 處理器來使用&參考$this->_refLOBs[$numlob]['VAR'] = &$var.

我們現在為了php5相容性在PEAR::isError()的get_class()函數小寫化。

CacheExecute 在5.04版中不能擷取快取資料集(4.98可以),已修正

在adodb.inc.php裡新的ADODB_Cache_File類別來檔案快取

Farsi 語言檔案的貢獻者Peyman Hooshmandi Raad (phooshmand#gmail.com)

建構你自訂的快取類別已儲存在$ADODB_CACHE的新API:

include "/path/to/adodb.inc.php";
$ADODB_CACHE_CLASS = 'MyCacheClass';

class MyCacheClass extends ADODB_Cache_File
{
function writecache($filename, $contents,$debug=false){...}
function &readcache($filename, &$err, $secs2cache, $rsClass){ ...}
:
}

$DB = NewADOConnection($driver);
$DB->Connect(...); ## MyCacheClass created here and stored in $ADODB_CACHE global variable.

$data = $rs->CacheGetOne($sql); ## MyCacheClass is used here for caching...

 

現在Memcache支援多重存放主機,只有在所有存放伺服器無法連聯絡時會產生連結的錯誤,使用範例如下:

$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = array($ip1, $ip2, $ip3); /// $db->memCacheHost = $ip1; still works
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)

$db->Connect(...);
$db->CacheExecute($sql);

4.98/5.04 13 Feb 2008

修正adodb_mktime問題,這問題造成$hrs的效能瓶頸。

新增mysqli支援adodb_getcount()。

從MetaType()移掉MYSQLI_TYPE_CHAR。

4.97/5.03 22 Jan 2008

作用的紀錄:$ADODB_ASSOC_CASE=1不能正確運作,更正。

修改在資料集類別裡的Fields()來支援FetchNextObject()裡顯示空欄位。

在ADOdb5作用中紀錄的實作,我們現在支援欄位名稱中的空格 - 我們使用_ using __set()來自動轉換空格,感謝Daniel Cook,見http://phplens.com/lens/lensforum/msgs.php?id=17200

從mysqli SelectLimit移除$arg3,見http://phplens.com/lens/lensforum/msgs.php?id=16243,感謝Zsolt Szeberenyi。

變更oci8 FetchField,他會回傳BLOB/CLOB/NCLOB的最大長度4000為-1,這是錯的。

CacheExecute有時在Windows假如不能鎖住快取檔案時會回傳錯誤,這是無害的並且會改成警告可以被忽略,另外adodb_write_file()程式碼改碼。

假如執行時間>= 0.05 秒的話,ADOdb perf程式碼變更為只紀錄sql,新的$ADODB_PERF_MIN變數存有最小的sql時間,任何下面有時間值的SQL在沒有紀錄時不會造成錯誤。

另外adodb_backtrace()現在追蹤1層而有時候真的culprit函數不會被顯示。

修正adodb_getcount()的一些問題,這個問題是那些不是postgres/oci8類的資料庫的。

變更mssql驅動Parameter()的參數從SQLCHAR到SQLVARCHAR:case 'string': $type = SQLVARCHAR; break.

在php5的adodb5.03版mssql驅動的問題是因為有些函數還不夠穩定,修正。

4.96/5.02 24 Sept 2007

在清除sql時oci8的ADOdb perf現在有non-table-locking程式碼,有點慢但是較佳的的透明度,在4.96a及5.02a中新增。

修正adodb計數的最佳化,Preg_match沒有正常運作,而且重寫adodb-lib.inc.php中的_adodb_getcount()的ORDER BY程式碼。

oci8的SelectLimit當offset=0時對於大型的資料集沒有最佳化,變更$nrows檢查。

啟用紀錄最佳化,在Set()新增關聯式陣列的支援。

現在假如EOF (沒有發現紀錄)GetOne回傳null,假如錯誤發生傳回false,使用ErrorMsg()/ErrorNo()來取得錯誤。

另外CacheGetRow及CacheGetCol在錯誤發生時傳回false,或在EOF時傳回空的array(),就像GetRow及GetCol。

Datadict現在允許不可變更大小的型態做改變,例如在ChangeTableSQL的VARCHAR變為TEXT -- Mateo Tibaquirá

新增BIT資料型別的支援在adodb-ado.inc.php及adodb-ado5.inc.php。

Ldap驅動沒有傳回真正的ldap錯誤訊息,修正。

實作GetRandRow($sql, $inputarr),Oci8的最佳化。

改變adodb5的作用紀錄以使用穩定的SetDatabaseAdapter()以及移除php4建構子,Bas van Beek bas.vanbeek#gmail.com。

另外在adodb5改變adodb-session2來使用穩定類別中的函數宣告,感謝Daniel Berlin。

新增"Clear SQL Log"在效能螢幕的底部。

在除錯模式裡Sessions2程式碼直接echo到螢幕,現在使用ADOConnection::outp()。

在mysql/mysqli,qstr(null)會傳回字串"null"來取代空的引號字串"''"。

Daniel Berlin (mail#daniel-berlin.de)在perf-postgres.inc.php新增了postgresql optimizeTable。

oci8新增5.2.1相容程式碼。

多重mssql驅動從@@identity變更為SCOPE_IDENTITY(),感謝 Stefano Nari。

在4.95版的程式碼清除在歐洲地區造成問題(像浮點數3.2被轉型為3,2),現在我們只在is_numeri失敗時清除。

新增使用$this->rsPrefix.'empty'來自訂ADORecordset_empty的支援,Josh Truwin提供。

在datadict程式碼裡新增Postgresql合適的ALterColumnSQL支援,感謝Josh Truwin。

在使用陣列資料集時於mysqli中新增較好的MetaType()支援。

在adodb-error.inc.php裡變更pqsql錯誤訊息的解析為不分大小寫。

4.95/5.01 17 May 2007

CacheFlush對outp()偵錯傳入無效的參數,修正。

新增adodb泰國語言檔,感謝Trirat Petchsingh rosskouk#gmail.com及Marcos Pont

新增mysql及mysqli的MetaColumns檢查支援。

CacheFlush不再刪除所有檔案/目錄,只有*.cache檔案會刪除。

DB2時間紀錄格式變為var $fmtTimeStamp = "'Y-m-d-H:i:s'";

在adodb-lib.inc.php新增一些程式碼清除來AutoExecute。

因為印刷的關係,所有在adodb-oracle.inc.php裡的連結會變成持續的,即使是非持續的,修正。

Oci8 DBTimeStamp現在使用24小時制來輸入,所以你可以在2個 DBTimeStamp之間執行字串比較。

在adodb-session2.inc.php有些PHP4.4相容的議題修正。

關於ADOdb 5.01修正一些adodb-datadict.inc.php MetaType跟PHP5相容的議題。

在adodb-ado5.inc.php裡$argHostname被除掉,修正。

Adodb5版本新增adodb_recordset_empty的迭代支援。

Adodb5版本假如可以的話更多錯誤檢查的程式碼現在將使用異常。

4.94 23 Jan 2007

作用紀錄:$ADODB_ASSOC_CASE=2運作不正常,修正,感謝gmane#auxbuss.com。

mysqli在BeginTrans()跟EndTrans()有錯誤,修正。

oci8在沒有資料庫連結時改善錯誤處理,感謝Andy Hassall。

在oci8 datadict裡超過30字元的名稱會被改成亂數名稱,感謝Eugenio, http://phplens.com/lens/lensforum/msgs.php?id=16182

新增var $upperCase = 'ucase'來存取以及ado_access驅動,感謝Renato De Giovanni renato#cria.org.br

關於Postgres64驅動假如在_query準備計畫失敗時,不能正確處理錯誤,修正,見http://phplens.com/lens/lensforum/msgs.php?id=16131

修正GetActiveRecordsClass()參考錯誤,見http://phplens.com/lens/lensforum/msgs.php?id=16120

關於qstr()在adodb-ado_mssql.inc.php裡新增空值的處理,感謝Felix Rabinovich。

Gaetano貢獻了Adodb-dict:+ 在data-dict裡INDEX的支援,例如:idx_ev1,這個使用INDEX關鍵字定義索引的功能在adodb4.94版中加入,下面的例子顯示多重索引,包括複合索引 idx_ev1。

  event_id I(11) NOTNULL AUTOINCREMENT PRIMARY,
event_type I(4) NOTNULL INDEX idx_evt,
event_start_date T DEFAULT NULL INDEX id_esd,
event_end_date T DEFAULT '0000-00-00 00:00:00' INDEX id_eted,
event_parent I(11) UNSIGNED NOTNULL DEFAULT 0 INDEX id_evp,
event_owner I(11) DEFAULT 0 INDEX idx_ev1,
event_project I(11) DEFAULT 0 INDEX idx_ev1,
event_times_recuring I(11) UNSIGNED NOTNULL DEFAULT 0,
event_icon C(20) DEFAULT 'obj/event',
event_description X


+ 避免產生的SQL包含在REPLACE的狀況下資料表中含有autoincrement欄位時從資料庫中刪除兩次序列號產生器的指令(在那些資料庫中會經由序列模擬)
+ 在跨資料庫工作時產生關於D及T欄位定義為DEFAULT值的任何日期,不只是"sysdate"值(只要它是指定使用adodb標準格式),見上例。

修正pdo的GetInsertID()支援,感謝Ricky Su。

oci8的Prepare()在錯誤發生時設定錯誤訊息。

新增'PT_BR'到SetDateLocale() -- 巴西 portugese。

在oci8裡編碼字集在*Connect()沒有設定正確

ADOConnection::Transpose()現在增加了第一個欄位名稱。

新增$ADODB_QUOTE_FIELDNAMES,假如設為true會自動在AutoExecute()、GetInsertSQL()、GetUpdateSQL()裡的欄位名稱加引號。

移轉現在新增了第一個欄位移轉後的欄位名稱。

新增adodb-active-record.inc.php裡$db在ADODB_SetDatabaseAdapter的===檢查,感謝Christian Affolter。

新增ErrorNo()到adodb-active-record.inc.php中,感謝ante#novisplet.com。

4.93 10 Oct 2006

在效能監控程式碼裡新增多重資料庫連結的支援(adodb-perf.inc.php),現在在多重資料庫連結裡的所有sql被存在一個資料庫裡($ADODB_LOG_CONN)。

新增MetaIndexes()到odbc_mssql。

新增連結屬性$db->null2null = 'null',在autoexecute/getinsertsql/getupdatesql裡這個值會被轉換成一個空值,假如你不想要空值的習慣可以設定這個成為有趣的無效值,見http://phplens.com/lens/lensforum/msgs.php?id=15902

在mysqli的路徑問題修正,感謝Andy。

修正session_schema2.xml裡的文字。

在oci8裡改變INT以回傳MetaColumns()裡$fld->max_length正確的精確度,感謝Eloy Lafuente Plaza。

修補postgres64 _connect來處理serverinfo(),見http://phplens.com/lens/lensforum/msgs.php?id=15887

新增空值欄位的pdo修正,見http://phplens.com/lens/lensforum/msgs.php?id=15889

關於預儲程序,失誤的連結id現在傳入mssql_query(),感謝Ecsy (ecsy#freemail.hu)。

4.92a 30 Aug 2006

postgres7驅動介面的語法錯誤,感謝Eloy Lafuente Plaza.

較小的錯誤修正 - adodb informix 10 個型別加入adodb.inc.php,感謝Fernando Ortiz.

4.92 29 Aug 2006

較好的odbtp日期支援。

新增IgnoreErrors()來忽略預設的錯誤處理。

在adodb-lib.inc.php中_adodb_getcount()函數有一些ORDER BY錯誤修正。

針對ibase及firebird,設定$sysTimeStamp = "CURRENT_TIMESTAMP"。

修正postgres連結錯誤:http://phplens.com/lens/lensforum/msgs.php?id=11057

因為其他使用者的抱怨,所以在$secs2cache==-1時變更CacheSelectLimit()來清除快取。

新增CacheExecute/CacheSelectLimit使用memcached的支援,需要memcache模組PECL擴充,用法:

$db = NewADOConnection($driver);
$db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = "126.0.1.1"; /// memCache host
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)

$db->Connect(...);
$db->CacheExecute($sql);

實作資料集的Transpose(),資料集必須使用ADODB_FETCH_NUM來擷取,第一個欄位成為欄位名稱。

$DB = NewADOConnection('mysql');
$DB->Connect(...);
$DB->SetFetchMode(ADODB_FETCH_NUM);
$rs = $DB->Execute('select productname,productid,unitprice from products limit 10');
$rs2 = $DB->Transpose($rs);
rs2html($rs2);

4.91 2 Aug 2006

主要的session程式碼重寫 .... 查session文件。

PDO bindinputarray的MySQL沒有設定正確(從true變為false)。

在$secs2cache==0時改變CacheSelectLimit()來重新快取,這是在SelectLimit被呼叫時清除快取的一個方式。

加入引號到mysql及mysqli:"SHOW COLUMNS FROM `%s`";

移除GetMenu()意外的optgroup處理,因php5相容修正ibase _BlobDecode,以及對於小blob的記憶體配置考量,感謝salvatori#interia.pl

Mysql驅動介面OffsetDate()的加速,對adodb-sessions有用。

修正PHP5相容的GetAssoc(),見http://phplens.com/lens/lensforum/msgs.php?id=15425

作用的紀錄 - 假如新增一筆紀錄而主鍵的值是空的,那麼我們不會加入這個欄位,我們會架設這個欄位是一個自動增加的欄位,這是mssql需要的。

改變postgres7 MetaForeignKeys()見http://phplens.com/lens/lensforum/msgs.php?id=15531

DB2在它有連結錯誤時現在可以傳回db2_conn_errormsg()。

4.90 8 June 2006

改變adodb-lib.inc.php的adodb_countrec()來允許LIMIT被用來加速減少沒有紀錄的計算。

新增postgres及oci8使用SetTransactionMode()的交易模式支援,這些交易模式影響所有該連結的隨後的交易。

感謝Halmai Csongor的建議。

移除db2驅動FetchField() $off = $fieldOffset - 1這一行,感謝Larry Menard。

加入使用__toString (如 Simple-XML)的Execute()繫結參數之PHP5物件支援,感謝Carl-Christian Salvesen。

在tohtml.inc.php裡的捨入不正確,修正。

在postgres裡MetaIndexes在欄位被刪時又再加入時因為attnum有gaps在裡頭而產生錯誤,見http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_i...,修正。

在fetchMode==ADODB_FETCH_ASSOC使用時mysql及mysqli的MetaForeignkeys不能運作,修正。

修正AutoExecute() 的參考錯誤。

新增macaddr postgres型別到MetaType,對應到'C'。

在adodb-ado5.inc.php中加入 _connect() $database及$dataProvider參數的支援,感謝Larry Menard。

在adodb-ado_mssql.inc.php中加入序列的支援,感謝Larry Menard。

新增ADODB_SESSION_READONLY,

加入session expiryref支援於crc32模式及LOB程式中。

清除postgres7驅動的_errorMsg,這樣在沒有錯誤發生時ErrorMsg()可以正確顯示。

新增BindDate及BindTimeStamp

4.81 3 May 2006

修正adodb-ado5.inc.php的_query()變數ref錯誤。

Mysqli setcharset 使用method_exists()的修正。

adodb-perf.inc.php的CreateLogTable()程式碼現在對於使用者定義的資料表可以運作。

ibase_blob_open()的錯誤修正,見http://phplens.com/lens/lensforum/msgs.php?id=14997

4.80 8 Mar 2006

加入activerecord支援。

假如你想要啟用MySQL 3.23的相容加入mysql $conn->compat323 = true,修正GetOne() Select-Limit 問題。

新增adodb-xmlschema03.inc.php的支援XML Schema version 3及更新adodb-datadict.htm文件。

Execute較好的記憶體管理,感謝Mike Fedyk。

4.72 21 Feb 2006

加入NConnect()的'new' DSN 參數。

Pager現在保護$PHP_SELF免於XSS的迫害,感謝James Bercegay及其他人。

ADOConnection::MetaType改變成可以正確設定$rs->connection。

Larry Menard、Dan Scott、Andy Staudacher、Bharat Mediratta貢獻新的原生DB2驅動。

mssql CreateSequence()的BEGIN TRANSACTION不正確修正,感謝Sean Lee。

adodb-lib.inc.php 的_adodb_countrecs()函數已經更版來處理更多的 ORDER BY變更。

4.71 24 Jan 2006

修正postgresql二進制字串的安全問題,感謝Andy Staudacher。

幾個DSN錯誤發現:

1.修正4.70中在DSN有底線時的DSN連結錯誤。

2.在PHP5中有_的DSN無法運作(PHP4中是好的),修正。

3. 加入PDO DSN連結的支援到NewADOConnection()及PDO::Connect()的資料庫參數。

在ADORecordSet_array裡oci8 datetime 旗標不能正確實作,修正。

新增BlobDelete()到postgres作為UpdateBlobFile()的對位。

修正GetInsertSQL()來支援oci8po。

修正postgresql qstr()字串中有\0的問題。

修正_adodb_getdriver()裡一些datadict驅動載入的問題。

針對PHP5相容在adodb-session.inc.php裡加入註冊shutdown函數session_write_close,見http://phplens.com/lens/lensforum/msgs.php?id=14200

4.70 6 Jan 2006

Danila Ulyanov修正很多ibase、oci8、postgres、mssql、odbc_oracle、odbtp等等驅動。

變更adodb-session.inc.php中mysql的二進位制提示的使用,見 http://phplens.com/lens/lensforum/msgs.php?id=14160

修正adodb-perf.inc.php中undomq()無效的變數參考。

修正adodb-perf.inc.php中http://phplens.com/lens/lensforum/msgs.php?id=14254所提的問題,fetchmode的 _DBParameter() 設定是錯的。

修正Andreas Sandblad在Secunia安全建議討論到的server.php及tmssql.php中安全相關議題,新增$ACCEPTIP = 127.0.0.1 及改變建議的root密碼來更安全。

在RenderLayout()後變更pager以關閉資料集。

4.68 25 Nov 2005

mysqli的PHP 5相容,MetaForeignKeys重複兩次及MYSQLI_BINARY_FLAG遺失。

PHP 5.1支援postgresql繫結參數使用?在>=10個參數時不能正常,修正,感謝Stanislav Shramko。

很多PDO的改善。

mysql MetaForeignKeys, $associative 參數的拼字錯誤修正。

4.67 16 Nov 2005

Postgresql not_null 旗標沒有正確的設為false,感謝Cristian MARIN。

我們現在檢查Replace()的key是否在fieldArray中,感謝Sébastien Vanvelthem。

_file_get_contents()函數在xmlschema不見了,修正。

新增年的週到SQLDate(),使用'W'旗標,感謝Spider。

在sqlite裡metacolumns被重複兩次,造成PHP 5問題,修正。

產生偵錯輸出相容的XHTML。

4.66 28 Sept 2005

在oci8的ExecuteCursor()不能正確的清除,修正。

"Alec Smecher" asmecher#smecher.bc.ca更新xmlschema.dtd。

強化SelectLimit,型別轉換nrows及offset為integer。

修正AutoExecute()及GetInsertSQL()的錯誤。

新增$conn->database這個屬性來保存資料庫名稱,舊的$conn->databaseName也被保留好向前相容。

變更_adodb_backtrace()相容性檢查為使用function_exists()。

postgresql MetaIndexes的錯誤修正,感謝Kevin Jamieson。

改善MySQL的OffsetDate,降低捨入錯誤。

Metacolumns新增到sqlite,感謝Mark Newnham。

PHP 4.4的 GetAssoc()相容性檢查。

新增php 5.1的postgresql繫結支援,感謝Cristiano da Cunha Duarte。

修正postgresql的OffsetDate(),型別轉換字串成date或timestamp。

mssql、odbc_mssql及postgresql的DBTimeStamp格式以配合其他的資料庫。

改變PDO_ to PDO:: 的PDO常數以支援最新的規格。

4.65 22 July 2005

還原mssql資料字典的'X'為'TEXT'來跟mssql驅動相容,現在你可以對mssql及oci8驅動設定$datadict->typeX = 'varchar(4000)'或'TEXT'或 'CLOB'。

在使用Oracle的DSN時新增字元集的支援。

_adodb_getmenu沒有使用fieldcount()來取得欄位數,修正。

Juan Carlos Gonzalez貢獻mysql/mysqli的MetaForeignKeys()。

mysqli 驅動的MetaDatabases()現在可以正確的傳回陣列,感謝Cristian MARIN。

CompleteTrans(false)沒有回傳false,修正,感謝JMF。

Pracle的AutoExecute()無法運作,修正,感謝José Moreira。

MetaType()新增到連結物件。

更多PHP 4.4參考回傳修正,感謝Ryan C Bonham及其他人。

4.64 20 June 2005

在資料字典裡,假如預設欄位值被設為''那麼在欄位產生時無法被應用,Eugenio修正。

postgres的MetaPrimaryKeys因為在4.63的true/false改變不能正常運作,修正。

oci8的測試ocifetchstatement,在最後會拒絕。

新增埠號到dsn處理,在postgres、mysql、mysqli、ldapport有支援。

新增'w'及'l'到mysqli的SQLDate()。

修正ldap _connect()的錯誤處理來變得更一致,也新增了ErrorMsg()處理到ldap。

對postgres及oci8在adodb-lib.inc.php的_adodb_getcount裡面新增聯集的支援。

rs2html()在空的日期時不能正常運作。

PHP 4.4的參考回傳修正。

4.63 18 May 2005

新增$nrows<0的檢查到mysqli的SelectLimit()中。

在adodb-perf.inc.php中新增OptimizeTable()及OptimizeTables(),Markus Staab貢獻。

PostgreSQL不一致性修正,true及false設為TRUE及FALSE,而在datadict-postgres.inc.php中的布林型別設為'L' => 'BOOLEAN',感謝Kevin Jamieson。

adodb-session.inc.php裡新的adodb_session_create_table()函數,Markus Staab貢獻。

新增空值檢查到UserTimeStamp()。

mysqlt裡的adorecordset typo修正,感謝Andy Staudacher。

GenID()在raiseErrorFn裡有錯誤,修正,感謝Marcos Pont。

資料字典名稱加引號現在在索引欄位可以正常處理 ( )--他們不是索引欄位的部份。

效能監控:(1) oci8 Ixora 檢查下跌; (2) 昂貴的sql改便所以只有那些count(*)>1的sql會顯示; (3)改變sql1欄位為length+crc32校驗和 - 這會跟之前的不相容。

我們在資料字典中重新映射firebird15到firebird。

4.62 2 Apr 2005

新增oci8、postgres及mysql的SQLDate 'w' (dow as 0-6 or 1-7)及'l' (dow as string)。

mysqli還原MetaType()到之前的版本。

chris, cblin#tennaxia.com改變資料字典的資料映射從:

oci8:  X->varchar(4000) XL->CLOB
mssql: X->XL->TEXT
mysql: X->XL->LONGTEXT
fbird: X->XL->varchar(4000)

到:

oci8:  X->varchar(4000) XL->CLOB
mssql: X->VARCHAR(4000) XL->TEXT
mysql: X->TEXT XL->LONGTEXT
fbird: X->VARCHAR(4000) XL->VARCHAR(32000)

新增$connection->disableBlobs到postgresql中來改善當bytea沒有使用時的效能(可以有2-5%改善)。

移除所有的HTTP_* 變數。

新增$rs->tableName在呼叫AutoExecute()前可以被設定。

Alex Rootoff rootoff#pisem.net 貢獻ukrainian語言檔。

新增新的mysql_option()支援使用$conn->optionFlags陣列。

新增支援ldap_set_option()使用$LDAP_CONNECT_OPTIONS全域變數,Josh Eldridge貢獻。

新增LDAP_*常數定義到ldap中。

新增支援布林繫結變數,我們使用$conn->false及$conn->true來保存設定false/true的值。

我們現在沒有關閉adodb-session.inc.php中的session連結,這樣其他的物件可以使用這個連結。

我們現在對oci8的$perf->tohtml() 中去掉Ixora SQL字串的結尾\0。

4.61 23 Feb 2005

MySQLi 新增支援mysqli_connect_errno()及mysqli_connect_error()。

很多alpha PDO驅動的改善。

為了容易輸入檢查效能監控紀錄引號字串繫結參數,感謝Jason Judge。

在連結Interbase/firebird時新增$role的支援。

在mysql及mysqli的MetaColumns()裡新增列舉的辨識,感謝Amedeo Petrella。

Interakt Online貢獻sybase_ase驅動,感謝Cristian Marin cristic#interaktonline.com。

從ADOFieldObject移除not_null、has_default及default_value。

修正在session write() 函數處理LOB時的Sessions程式碼的鍵的引號。

Sessions程式碼新增adodb_session_regenerate_id()藉由動態改變session cookie code來降低session hijacking的風險,感謝Joe Li。

效能監控,因為PHP的錯誤在PHP 4.3.10 及5.0.0-5.0.3中查詢CPU不能正常運作,所以我們特別標示這些版本。

Postgresql, UpdateBlob()新增程式碼來處理 type==CLOB。

4.60 24 Jan 2005

實作PEAR DB的autoExecute(),因為我不喜歡在字串可以良好運作時使用常數所以簡單的設計。

_rs2serialize現在可以更新$rs->sql及$rs->oldProvider。

新增autoExecute()。

新增postgres8驅動的支援,目前只是重映射到postgres7驅動。

改變oci8 _query()所以在元素大小>4000時OCIBindByName()設定長度到-1,這個提供LONG較好的支援。

新增SetDateLocale()的netherlands (Nl)支援。

在樞紐分析程式碼中拼字錯誤($iff應該是$iif)。

mysql insert_id()在mysql 3.x中不正常,修正。

"\r\n"在匯出資料時不能正確轉換成空格,修正。

mysqli的_nconnect()不能正確傳回值,修正。

Arne Eckmann 貢獻丹麥語言檔。

新增PHP5的clone()支援到FetchObject()。

從odbc_mssql移除SQL_CUR_USE_ODBC。

4.55 5 Jan 2005

發現資料庫的Execute()繫結參數錯誤無法支援原生的繫結。

DropSequence()現在正確使用預設的參數。

現在Execute()忽略浮點數地區性設定,所以1.23不會轉換成1,23。

SetFetchMode()沒有適當地存在adodb-perf,懷疑的sql及昂貴的sql,修正。

新增INET到postgresql metatypes,感謝motzel。

允許oracle在adodb-lib.inc.php中在使用_adodb_getcount計算時提示工作,感謝Chris Wrye。

改變mysql insert_id()來使用SELECT LAST_INSERT_ID()。

假如在資料字典裡的alter欄位沒有修改實際欄位的型別/大小,那麼它會從alter col程式碼中移除,Mark Newham修正,並不完美的MetaType() !== ActualType()。

postgresql在metacolumns()裡新增檢視欄位的處理,感謝Renato De Giovanni。

新增informix MetaPrimaryKeys及MetaColumns修正空值位元,感謝 Cecilio Albero。

從perf程式碼中移除廢除的connection_timeout()。

新增adodb-csv.inc.php的arrayClass支援。

RSFilter現在接受$array($obj, 'methodname')這樣格式的方法,感謝blake#near-time.com。

改變CacheFlush為$cmd = 'rm -rf '.$ADODB_CACHE_DIR.'/[0-9a-f][0-9a-f]/';

為了較好的指標一致性,新增程式碼在$rs->Close() 呼叫時釋放oci8的ref指標,也注意CLose()是由Get*函數內部呼叫。

在樞紐分析時新增存取IIF的支援,感謝Volodia Krupach。

新增mssql時間戳記的資料字典支援,感謝Alexios。

Informix pager 修正,感謝Mario Ramirez。

ADODB_TABLE_REGEX現在包括':',Mario Ramirez釋出。

Mark Newnham貢獻oci8及db2的MetaIndexes。

4.54 5 Nov 2004

現在你可以在oci8裡在做Connect()前可以設定$db->charSet = ?? 。

新增adodbFetchMode到sqlite。

Perf程式碼,在adodb_log_sql()新增字串型別轉換為substr。

Postgres: 改變BlobDecode()為use po_loread,新增新的$maxblobsize參數,並且現在它回傳blob而不是送到stdout - 確認提到相容字串,另外新增$db->IsOID($oid)函數;使用啟發式而非保證100%可以運作。

"El-Shamaa, Khaled" k.el-shamaa#cgiar.org貢獻阿拉伯語言檔。

PHP5 例外沒有適當處理@協定,修正。

新增postgresql的ifnull處理(使用coalesce)。

新增Postgresql 8.0的metatables()支援(不再使用pg_% 字典資料表)。

改善Sybase ErrorMsg()函數,Gaetano Giunta貢獻。

改善oci8 SelectLimit()來使用Prepare(),Cristiano Duarte貢獻。

在ifx_fetch_row()將$row參數型別轉換成int,感謝stefan bodgan。

Ralf becker貢獻postgresql、sapdb、mysql資料字典處理的改善:
- MySql及Postgres的MetaType報告每一個int欄位,這個欄位是作為序列的主鍵及唯一鍵的部份。
- Postgres不報告十進位型別的尺度
- MaxDB使用空格來填充非字串型別的預設值
- MySql現在正確地轉換列舉欄位為varchar

Ralf也改變了Postgresql資料字典:
- 你不可以在postgres一次新增NOT NULL欄位,他們需要先新增為NULL然後再改變成NOT NULL。
- AlterColumnSQL不能改變有數字的varchar欄位成integer欄位,postgres需要一個清楚的轉換
- 假如再生的序列名稱是舊的名稱(非隱含序列)的話無法設定正確值,現在總是新的隱含序列名稱被使用

Sergio Strampelli在資料字典程式碼中另外新增$intoken檢查於Lens_ParseArgs()。

4.53 28 Sept 2004

在資料集裡FetchMode快取有時對應到原生的db fetchMode,一般來說是沒什麼關係,但是當使用快取資料集時,我們需要切換回使用adodb fetchmode,所以我們在$rs->adodbFetchMode裡快取這個假如它跟db fetchMode不同的話。

對於informix我們現在設定canSeek = false驅動因為stefan bodgan告訴我seeking無法運作。

SetDateLocale()現在仍不能運作 ;-) 感謝david#tomato.it

在sapdb驅動介面裡設定$_bindInputArray = true,需要clob支援。

修正一些PEAR::DB在isError()及isWarning模擬的主題,感謝Gert-Rainer Bitterlich。

使用在getupdatesql的Empty()沒有strlen()檢查,修正。

新增unsigned偵測到mysql及mysqli驅動,感謝dan cech。

新增匈牙利語言檔,感謝 Halászvári Gábor。

改善資料字典SQL產生的欄位型別格式化(新增$widespacing參數到_GenField)。

oci8的資料字典的DROP CONSTRAINTS拼錯,修正,感謝Mark Newnham。

依據連結改變odbtp成動態資料庫型別,例如在連結到mssql資料庫時從 'odbtp'變為 'odbtp_mssql'。

在資料字典中MySQL I4錯誤地映射到MEDIUMINT,而實際上是I3,修正。

修正mysqli MetaType()的辨識,Mysqli不像mysql擴充那樣回傳數值型別,感謝Francesco Riosa。

VFP odbc 驅動curmode設定錯誤,造成memo欄位的問題,修正。

Odbc驅動不能辨識odbc版本2驅動的日期型別,修正,感謝Bostjan。

改變TableSQL()修正到datadict-db2.inc.php中,Mark Newnham貢獻。

odbc的效能監控改善,現在我們嘗試在效能的程式碼中在sysTimeStamp是空的時候使用date()來手動設定sysTimeStamp。

所有ADO錯誤在PHP5中會拋出例外,所以我們在PHP5中藉由新增新的adodb-ado5.inc.php驅動來新增例外處理到ado中。

新增IsConnected()。在連結物件連接時傳回true,Luca.Gioppo貢獻。

"Ralf Becker" RalfBecker#digitalROCK.de貢獻新的sapdb資料字典驅動及實作oracle、mssql、postgresql、mysql及sapdb欄位及資料表更名很大的修正,見新的RenameTableSQL()及RenameColumnSQL()函數。

我們現在檢查ExecuteCursor來看看PrepareSP是否會一開始就呼叫。

對 $dd->alterCol改變oci8資料字典來使用MODIFY,感謝Mark Newnham。

4.52 10 Aug 2004

當效能紀錄開啟時Replace()中有發現到錯誤,在ADOdb 4.50修正。

Replace() 檢查更新stmt,假如更新stmt失敗,現在我們會馬上傳回,感謝alex。

新增$ADODB_FORCE_TYPE的支援在GetUpdateSQL/GetInsertSQL中,感謝niko。

新增ADODB_ASSOC_CASE支援到postgres/postgres7驅動介面。

在oci8支援DECLARE stmt,感謝Lochbrunner。

4.51 29 July 2004

新增adodb-xmlschema 1.0.2,感謝dan及richard。

新增新的adorecordset_ext_*類別,假如mysql、mysqlt及oci8 (但不是oci8po)的ADOdb擴充安裝,對movenext我們會使用超快的ADOdb擴充程式碼。

新增概要支援到mssql及odbc_mssql MetaPrimaryKeys()。

在_query()函式中當繫結輸入陣列參數時更新MSSQL驅動介面來支援PHP NULL及布林值,感謝Stephen Farmer。

新增mssql UpdateBlob()的clob支援,感謝gfran#directa.com.br。

新增postgresql的normalize支援(true=lowercase 資料表名稱,或false=case-sensitive 資料表名稱)到MetaColumns($table, $normalize=true)。

在ADO中的PHP5變異日期不正常,修正adodb-ado.inc.php。

在很多版本中常數ADODB_FORCE_NULLS運作不正常(關於GetUpdateSQL),修正,而且GetUpdateSQL現在會剝去ORDER BY-感謝Elieser Leão。

oci8的效能監控現在假如太高/低時會動態地將optimizer_* params亮度顯示。

新增dsn支援到NewADOConnection/ADONewConnection。

修正_adodb_pageexecute_all_rows()的頁面界線的錯誤,感謝"Sergio Strampelli" sergio#rir.it。

加速mysql及oci8驅動的movenext。

移動偵錯程式碼_adodb_debug_execute()到adodb-lib.inc.php中。

修正postgresql bytea偵測錯誤,見http://phplens.com/lens/lensforum/msgs.php?id=9849

修正PHP5中ibase datetimestamp typo,感謝stefan。

移除odbtp驅動最後的空白。

新增db2 metaprimarykeys 修正。

mysql及oci8的最佳化到MoveNext(),其他Get* 函式的加速。

4.50 6 July 2004

版本跳到4.50以避免跟PHP 4.3.x系列產生混淆。

新增db2 metatables及metacolumns擴充。

新增alpha PDO驅動介面,很大的錯誤,只在odbc下可以使用。

測試mysqli,見poorAffectedRows = true,清除movenext()及_fetch()。

PageExecute在php5中不能使用(傳回val而不是variable),Dmytro Sychevsky sych#php.com.ua報告,已修正。

mysql的MetaTables() $showschema 參數不能跟舊版本的adodb相容,修正。

在使用non-select stmts時變更mysql GetOne()可以跟mysql3.23配合使用(例如SHOW TABLES)。

在datadict-oci8.inc.php中變更TRIG_ prefix到一個變數中,感謝Luca.Gioppo#csi.it。

新的adodb-time程式碼,我們允許你來定義你自己的daylights savings 函式,adodb_daylight_sv 在1970年前日期,假如(有時候在一個include裡),那麼你可以更正daylights savings,見http://phplens.com/phpeverywhere/node/view/16#daylightsavings更多資訊。

新的sqlitepo驅動介面,這是因為在sqlite裡像其他的驅動介面一樣assoc模式錯誤,換句話說當selecting (joining)多重資料表時,在"sqkite"驅動介面assoc模式下資料表名稱被含括在assoc keys裡,在"sqlitepo"驅動介面裡,資料表名稱會從傳回的欄位名稱拆開來,當這個結果產生衝突,第一個欄位會修先取得,感謝Herman Kuiper herman#ozuzo.net。

新增$forcenull參數到GetInsertSQL/GetUpdateSQL,Marco Aurelio Silva的想法。

更多GetMenu XHTML的改變,感謝Jeremy Evans。

修正一些ibase日期的問題,感謝stefan bogdan。

mysqli驅動介面的改善來支援$ADODB_COUNTRECS。

在從socket讀取串流時修正adodb-csvlib.inc.php的問題,我們需要連續地投入串流。

4.23 16 June 2004

新的interbase/firebird修正感謝,驅動修正一個關於在result陣列取得欄位名稱的問題,以及更正一組的資料轉換,另外我們預設了firebird的dialect3,以及ibase sysDate屬性是錯的,改變轉換為timestamp。

datadict驅動被設定來將資料表及欄位引號,因為這是保留字在TikiWiki備用作欄位名稱的唯一的方式,TikiPro是整理而且我希望能夠產生一個THAT的建立,這個是使用我認為合適的UPPERCASE欄位及資料表名稱的使用,TikiWiki的轉換對ADOdb可以這樣幫忙,但是只有在TikiPro裡資料庫才能完全整理 ...

修改_gencachename()來含括在名稱hash裡的fetchmode,這個意思是你應該直接清除你的快取在安裝這個版本時這個快取名稱的演算法則變更後才有效。

現在Cache*函式可以在安全模式下運作,因為我門在安全模式下沒有新增子目錄在$ADODB_CACHE_DIR裡,在非安全模式下我們仍然可以建立子目錄,修改_gencachename()現在完成。

在連結類別裡新增$gmt參數(true/false)到UserDate及UserTimeStamp,來強迫輸入(當地時間)轉換成UTC/GMT。

Mssql datadict不支援INT型別(不予許size param),新增_GetSize()到 datadict-mssql.inc.php。

關於borland_ibase,BeginTrans()將:

   $this->_transactionID = $this->_connectionID;

改變為

   $this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);

修正mysqi_field_seek()的typo,感謝Sh4dow (sh4dow#php.pl)。

LogSQL在Firebird/Interbasex裡有錯誤,修正。

Postgres: 使得errorno()處理更一致,感謝Michael Jahn, Michael.Jahn#mailbox.tu-dresden.de。

新增informix更新到較好的支援metatables、metacolumns,感謝"Cecilio Albero" c-albero#eos-i.com。

Cyril Malevanov貢獻oci8更新以支援LOB參數的傳遞:

	$text = 'test test test';
$sql = "declare rs clob; begin :rs := lobinout(:sa0); end;";
$stmt = $conn -> PrepareSP($sql);
$conn -> InParameter($stmt,$text,'sa0', -1, OCI_B_CLOB);
$rs = '';
$conn -> OutParameter($stmt,$rs,'rs', -1, OCI_B_CLOB);
$conn -> Execute($stmt);
echo "return = ".$rs."<br>";

因為他說LOBs的限制是:

 - 在繫結前使用OCINewDescriptor
- 假如Param是IN在每一個執行前使用save(),這可以為你自動完成。
- 假如Param是OUT在每一個後使用load(),這可以為你自動完成。
- 當我們繫結$var為LOB時,我們建立新的描述符並且將它傳回作為Bind Result,所以假如我們想要使用OUT參數,我們必須在某些地方儲存
&$var來從LOB載入load()資料到它那裡。
- 現在OUT params無法運作(應該不是大問題來修正它)
- 現在大量的繫結也不能運作(我在以前已經提出)

簡化Connect()及PConnect()的錯誤處理。

當擴充沒有載入時,Connect()及PConnect()會傳回null,在連結錯誤時,fns會傳回false。

CacheGetArray() 新增到程式碼中。

新增Init()到adorecordset_empty()。

改變postgres64驅動,MetaColumns()沒有關閉預設值if :: detected (預設值的型別轉換)的引號。

新增test: if (!defined('ADODB_DIR')) die(),用來避免駭客偵測檔案路徑。

改變metaTablesSQL來忽略Postgres 7.4資訊概要(sql_*)。

新的波蘭語言檔來自Grzegorz Pacan

新增_adodb_getcount()的UNION支援。

新增安全檢測ADODB_DIR來限制路徑敗露的問題,postnuke團隊請求。

新增較好的錯誤訊息支援到oracle驅動,感謝Gaetano Giunta。

新增showSchema支援到mysql。

在oci8的繫結不能正確處理$name=false,修正。

假如擴充沒有載入Connect()、PConnect()、NConnect()將傳回null。

4.22 15 Apr 2004

移動文件docs到自己的adodb/docs資料夾。

在Replace()裡當compressed/encrypted的資料引號起來時sssion的錯誤修正。

Josh Eldridge貢獻Netezza驅動及LDAP驅動。

GetMenu現在使用rtrim()在值上來取代trim()。

改變MetaColumnNames來傳回一個關聯式陣列,索引鍵是大寫的蘭為明稱。

建議修正adodb-ado.inc.php affected_rows來支援PHP5的變異,感謝Alexios Fakos。

Valentin Sheiretsky valio#valio.eu.org貢獻保加利亞語言檔。

stefan bogdan貢獻羅馬尼亞語言檔。

GetInsertSQL現在會檢查$rs的資料表(字串),並且將自動為那個資料表建立一個資料集,Walt Boring貢獻,另外也新增OCI_B_BLOB在繫結裡來符合Walt的需求 - 希望他不會對其他東西有影響 :-)

在_initrs()有些較小的postgres加速。

假如 MetaColumns傳回空值現在ChangeTableSQL會檢查,感謝Jason Judge。

新增ADOConnection::Time(),傳回unix時間戳記格式的目前資料庫時間或是 false。

4.21 20 Mar 2004

對於VFP驅動我們不再在SelectLimit新增SELECT TOP X除非ORDER BY有存在。

Pim Koeman貢獻荷蘭語言檔adodb-nl.inc.php。

Rick Hickerson新增CLOB支援到db2資料字典。

新增odbtp驅動,感謝"stefan bogdan" sbogdan#rsb.ro。

改變PrepareSP()第2個參數$cursor預設值為true (之前是false),修正oci8向前相容OUT params的問題。

修正在adodb-time.inc.php的月份計算錯誤,2102-June-01出現為2102-May-32。

更新PHP5 RC1迭代支援、API改變、hasMore()更名為valid()。

改變序列快取資料集的內部格式,當我們儲存一個版本編號時,這可以向前相容。

在ADOLoadCode()中當驅動檔案沒有發現時錯誤處理會有瑕疵,修正。

4.20 27 Feb 2004

更新到AXMLS 1.01。

Edward Jaramilla修改postgres7的MetaForeignKeys,可以在pg 7.4下執行。

對GetInsertSQL/GetUpdateSQL數值欄位來說現在數值接受函式呼叫或是序列。

改變'delete from $perf_table' to ""的引號,感謝Kehui (webmaster#kehui.net)

新增ifx的ServerInfo(),以及putenv trim的修正,感謝Fernando Ortiz。

新增addq()這是跟addslashes()類似的函式。

測試php5b4,修正php5例外的相容問題及sybase。

Carl-Christian Salvesen新增路徑到mssql _query來支援繫結超過4000個字元。

Mike建議更新PHP5例外處理,$errno必須是數值。

新增ADODB_TABLE_REGEX的雙引號(")。

對於oci8,Prepare(...,$cursor) $cursor的意思是意外的在4.11顛倒,這也造成ExecuteCursor()問題,因為它會內部呼叫Prepare(),感謝William Lovaton。

在連結物件裡的dateHasTime屬性因為一致性的問題現在更名為datetime,這樣可以打破公元前bc。

Csongor Halmai報告db2 SelectLimit的input陣列不能執行,修正。

4.11 27 Jan 2004

Csongor Halmai報告db2繫結錯誤,還原到之前的模擬繫結。

Dan Cech修改datadict程式碼,新增DropIndex的支援,不重要的清除。

perf-oci8.inc.php中的表格拼錯,改變v$conn_cache_advice成v$db_cache_advice,Steve W報告。

UserTimeStamp及DBTimeStamp不能正確處理YYYYMMDDHHMMSS格式,Mike Muir報告,修正。

改變oci8 Prepare(),不自動配置OCINewCursor,除非第二個參數設為true,這不能向前相容,假如使用Prepare/Execute而不用ExecuteCursor時,Chris Jones報告。

新增InParameter()及OutParameter(),Parameter()的外覆函式,但因為自我紀錄所以較好。

在ActualType()新增'R'處理到datadict-mysql.inc.php中。

新增ADOConnection::SerializableRS($rs),傳回可以序列化為session的資料集。

新增"Run SQL"來提昇UI()。

來自Heinz Hombergs將adodb-mysqli.inc.php、adodb-oci8.inc.php及datadict-oci8.inc.php裡的其他拼字更正。

Heinz Hombergs貢獻ibase的MetaIndexes()。

4.10 12 Jan 2004

Dan Cech貢獻很多資料字典來支援名稱引號(加`)以及drop table/index的改變。

Informix新增正確的cursorType屬性,預設情況下保留IFX_SCROLL,但是你可以因為效能關係改變成0 (non-scrollable cursor)。

新增ADODB_View_PrimaryKeys()來傳回檢視主鍵給MetaPrimaryKeys()。

adodb-cn.inc.php的簡體中文檔來自cysoft。

在adodb-datadict.inc.php中新增ctype_alnum的檢查,感謝Jason Judge。

新增連結參數到ibase Prepare(),Daniel Hassan修正。

新增nameQuote來將連到物件的識別字及名稱引號起來,Jason Judge請求,另外資料字典的解析現在偵測`field name`並且正確地產生有空格的欄位名稱。

BOOL型別不能辨別L,修正。

修正ADODB_DIR中的session檔案更新,以及向前相容到4.05版(2003/12/15)

新增概要到postgresql MetaTables,感謝col#gear.hu。

postgresql有blob欄位的空資料集沒有正確設定EOF,修正。

CacheSelectLimit到SelectLimit的內部參數是錯的,感謝Nio。

修改adodb_pr()及adodb_backtrace()來支援命令列的使用(例如非html)。

修正一些fr及it語言錯誤,感謝Gaetano G。

Gaetano G直接新增contrib及adodb rs到xmlrpc convertor。

修正當_skiprow1是true時的陣列資料集錯誤,感謝Gaetano G。

修正當count是false時樞軸資料表的程式碼。

 

4.05 13 Dec 2003

新增MetaIndexes到data-dict程式碼 - 感謝Dan Cech。

Ross Smith重寫session程式碼,移動程式碼到adodb/session目錄。

在連結到多數驅動時新增函式存在的檢查,這樣就不會因不知的函式錯誤而崩潰。

因為sql指令失敗在sql資料表沒有產生時有GenID()的智能交易會失敗,感謝Mark Newnham,

新增$db->length可以保存所傳回函式名稱的strlen。

修正ADONewConnection中錯誤驅動傳遞太少參數到error-handler的錯誤處理。

在_GetSize裡資料字典不能像16.0那樣正確處理型別,修正。

Oci8驅動的SelectLimit()錯誤 &= 改為使用 =&,感謝Swen Thümmler。

Jesse Mullan建議在output buffering啟用時不要清除outp,這是因為 Apache 2.0錯誤,新增。

修正adodb-datadict.inc.php中因PHP5的MetaTables/MetaColumns傳回ref錯誤。

Arjen de Rijke貢獻新的mysqli驅動,依據adodb 3.40驅動,然後jlim新增BeginTrans、CommitTrans、RollbackTrans、IfNull、SQLDate,以及修正傳回ref的錯誤。

$ADODB_FLUSH新增,在偵錯outp中假如true就強迫清除,預設是false,在較早的版本中outp預設會清除,這個清除不相容於apache 2.0。

Mysql驅動的GenID()函式在sql登錄開啟時不能執行,修正。

$ADODB_SESSION_TBL沒有宣告為全域變數,假如在函式中沒有含括adodb-session.inc.php就不能用,修正。

在_adodb_getcount()中輸入陣列沒有傳到Execute(),修正。

4.04 13 Nov 2003

切換回到foreach - 比list-each快。

修正ado驅動的錯誤 - 消去有日期欄位的$this->fields。

效能監控、檢視SQL、說明計畫在strlen($SQL)>max($_GET length)不能執行,修正。

效能監控,oci8驅動新增記憶體排序比例。

新增隨機屬性,傳回SQL來產生一個介於0跟1之間的浮點數。

4.03 6 Nov 2003

adodb-php4.inc.php及adodb-iterators.inc.php的路徑設錯。

interbase中更新的SQLDate支援hours/mins/secs,感謝ari kuorikoski。

pgsql的持續連結強迫自動回復 - 很明顯地在4.3.4之前pgsql不能正確回復,見http://bugs.php.net/bug.php?id=25404

4.02 5 Nov 2003

adodb_error_pg()的一些錯誤修正,感謝Styve。

LogSQL()產生偽造的Insert_ID()錯誤,修正。

當LogSQL()開啟時Insert_ID會妨礙Affected_Rows()及Replace(),修正。

更多的foreach迴圈最佳化使用list/each。

在ADO驅動中Null日期處理錯誤(它變成31 Dec 1969!)。

Heinz Hombergs貢獻mysql MetaColumns更新 - 新增scale、讓firebird/interbase的interbase MetaColumns可以執行,以及新增lang/adodb-de.inc.php。

新增INFORMIXSERVER環境變數。

新增interbase/firebird的$ADODB_ANSI_PADDING_OFF。

PHP 5 beta 2的相容檢查,Foreach (迭代)支援,例外支援。

4.01 23 Oct 2003

tohtml.inc.php的rs2html()的錯誤修正,這個錯誤會產生空白資料表儲存格。

修正在logsql()開啟時insert_id()不正確地產生。

修改PostgreSQL _fixblobs來使用list/each以取代foreach。

Informix ErrorNo()正確實作。

修改幾個地方來使用list/each,包括GetRowAssoc()。

新增UserTimeStamp()來連結類別。

新增oci8po的$ADODB_ANSI_PADDING_OFF。

4.00 20 Oct 2003

將adodb-xmlschema升級到2003/8/1的版本。

修正rs2html警告訊息,感謝Filo。

修正odbc_mssql/mssql SQLDate(),他的小時是錯的。

新增sybase.的MetaColumns及MetaPrimaryKeys,感謝Chris Phillipson。

新增MySQL及PostgreSQ 資料字典的自動引號,這是Karsten Dambekalns建議的。

3.94 11 Oct 2003

datadict-oci8.inc.php中的觸發建構不能執行,因為所有的cr/lf's必須被移除。

當logging開啟時很多資料庫的ErrorMsg()/ErrorNo()不能執行,修正。

移除全域變數$ADODB_LOGSQL因為它在多重連結時不能執行。

新增sybase的SQLDate支援,感謝Chris Phillipson。

Postgresql的gsql結果集資源的檢查是錯誤的,Bharat Mediratta bharat#menalto.com修正,adodb-postgres64.inc.php有些更新應用到 _insertid及_affectedrows。

新增postgresql的NConnect支援。

新增Sybase資料字典支援,感謝Chris Phillipson。

$perf->UI()大規模的改善,例如說明會開啟新的視窗、我們會顯示呼叫sql的指令....等等。

Perf Monitor UI在magic quotes開啟時可以執行。

rsPrefix宣告兩次,移除。

Oci8 預儲程序支援,例如"begin func(); end;"在_query是錯誤的,修正。

Tiraboschi Massimiliano貢獻義大利語言檔。

Fernando Ortiz, fortiz#lacorona.com.mx,貢獻informix效能監控。

新增postgresql的_varchar (varchar arrays)支援,PREVOT Stéphane報告。


0.10 Sept 9 2000 第一版

舊版的變動紀錄移到old-changelog.htm