相關(guān)學(xué)習(xí)資料
http://www.php.net/manual/zh/refs.database.phphttp://www.php.net/manual/zh/internals2.pdo.phphttp://bbs.phpchina.com/thread-184537-1-1.htmlhttp://www.metsky.com/archives/660.htmlhttp://www.phpbuilder.com/http://www.w3school.com.cn/php/php_db_odbc.asphttps://www.ibm.com/developerworks/cn/opensource/os-php-odbc/http://blog.csdn.net/deflag/article/details/743597http://www.informit.com/articles/article.aspx?p=31839&seqNum=3http://zh.wikipedia.org/wiki/Berkeley_DBhttp://blog.csdn.net/zuiaituantuan/article/details/5996376
目錄
1. PHP數(shù)據(jù)庫驅(qū)動簡介2. PHP連接數(shù)據(jù)庫的不同方式
1. PHP數(shù)據(jù)庫驅(qū)動簡介
驅(qū)動是一段設(shè)計用來于一種特定類型的數(shù)據(jù)庫服務(wù)器進(jìn)行交互的軟件代碼。驅(qū)動可能會調(diào)用一些庫。類似于Java中的數(shù)據(jù)庫驅(qū)動的概念
1. JDBC-ODPC橋:它將JDBC API映射到ODPC API。再讓JDBC-ODPC調(diào)用數(shù)據(jù)庫本地驅(qū)動代碼(也就是數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫操作二進(jìn)制代碼庫,例如Oracle中的oci.dll)2. 本地API驅(qū)動直接將JDBC API映射成數(shù)據(jù)庫特定的客戶端API,即通過客戶端加載數(shù)據(jù)庫廠商提供的本地代碼庫(C/C++等) 3. 網(wǎng)絡(luò)協(xié)議驅(qū)動(主流)這種類型的驅(qū)動給客戶端提供了一個網(wǎng)絡(luò)API,客戶端上的JDBC驅(qū)動程序使用套接字(Socket)來調(diào)用服務(wù)器上的中間件程序,后者在將其請求轉(zhuǎn)化為所需的具體API調(diào)用。4. 本地協(xié)議驅(qū)動(主流)這種類型的驅(qū)動使用Socket,直接在客戶端和數(shù)據(jù)庫間通信。它是一種直接與數(shù)據(jù)庫實例交互的JDBC這種驅(qū)動是智能的,它知道數(shù)據(jù)庫使用的底層協(xié)議,也是目前最主流使用的JDBC驅(qū)動,我們本章的重點就是它
而對于PHP來說,同樣主流使用的也是網(wǎng)絡(luò)協(xié)議驅(qū)動、本地協(xié)議驅(qū)動,即MySQL客戶端庫、MySQL Native驅(qū)動庫。 這些庫實現(xiàn)了用于和MySQL數(shù)據(jù)庫服務(wù)器進(jìn)行交互的底層協(xié)議。
數(shù)據(jù)庫驅(qū)動位于PHP和數(shù)據(jù)庫進(jìn)行通信的最底層,不同的數(shù)據(jù)庫廠商都會在基于某個框架的前提下實現(xiàn)自己的驅(qū)動,用以提供基本功能、以及特定數(shù)據(jù)庫的高級功能。
在驅(qū)動層之上是'連接器'、或者是適配器抽象層,用于PHP代碼和數(shù)據(jù)庫進(jìn)行連接,程序員可以使用PDO(PHP Database Object)、或者直接使用擴(kuò)展接口(mysql、mysqli)這些暴露出來的API與底層數(shù)據(jù)庫進(jìn)行通信。
數(shù)據(jù)庫廠商提供的底層數(shù)據(jù)庫驅(qū)動
mysql: http://www.mysql.com/products/connector/oracle: http://www.oracle.com/technetwork/indexes/downloads/index.html#databasesqlserver: http://msdn.microsoft.com/zh-cn/library/cc296170(SQL.90).aspx ...
文件型數(shù)據(jù)庫
文件型是一種基于文件的數(shù)據(jù)庫引擎,而且使用文件I/O(輸入/輸出)函數(shù)來存儲和讀取來自磁盤上文件的數(shù)據(jù)庫。它普遍也比關(guān)系型數(shù)據(jù)庫(例如Mysql)小很多很多(例如典型的文件型數(shù)據(jù)庫SQLite命令行版本的大小小于200KB),同時,文件型數(shù)據(jù)庫而且支持你所熟悉的大部分SQL命令,同時具有易于攜帶的特點
接下來,我們以上面這張大圖作為開始,逐一學(xué)習(xí)PHP連接數(shù)據(jù)庫的不同方式、以及它們在不同業(yè)務(wù)場景下的優(yōu)缺點
2. PHP連接數(shù)據(jù)庫的不同方式
0x1: 使用擴(kuò)展API接口與數(shù)據(jù)庫通信
PHP代碼是由一個核心,一些可選擴(kuò)展組成了核心功能。PHP 的MySQL相關(guān)擴(kuò)展,比如mysqli,mysql都是基于PHP擴(kuò)展框架實現(xiàn)的。
擴(kuò) 展一個典型的作用就是暴露一個API給PHP程序員,允許擴(kuò)展自己的功能可以被程序員使用。當(dāng)然,也有一部分基于PHP擴(kuò)展框架 開發(fā)的擴(kuò)展不會給PHP程序員暴露API接口。比如說PDO MySQL驅(qū)動擴(kuò)展,就沒有向PHP程序員暴露API接口,但是向它上層的PDO層提供了一個接口。
關(guān)于PHP擴(kuò)展的編寫請參閱另一篇博文http://www.cnblogs.com/LittleHann/p/3562259.html
在實際編程中,使用頻度最多的還是以擴(kuò)展API的方式去連接數(shù)據(jù)庫
extension=php_mysql.dll
這 是設(shè)計開發(fā)允許PHP應(yīng)用與MySQL數(shù)據(jù)庫交互的早期擴(kuò)展。mysql擴(kuò)展提供了一個面向過程的接口,并且是針對MySQL4.1.3或更早版本設(shè)計 的。因此,這個擴(kuò)展雖然可以與MySQL4.1.3或更新的數(shù)據(jù)庫服務(wù)端 進(jìn)行交互,但并不支持后期MySQL服務(wù)端提供的一些特性
mysql擴(kuò)展的源代碼在PHP擴(kuò)展目錄ext/mysql下
<?php // 連接、選擇數(shù)據(jù)庫 $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password') or die('Could not connect: ' . mysql_error()); echo 'Connected successfully'; mysql_select_db('my_database') or die('Could not select database'); // 執(zhí)行 SQL 查詢 $query = 'SELECT * FROM my_table'; $result = mysql_query($query) or die('Query failed: ' . mysql_error()); // 以 HTML 打印查詢結(jié)果 echo '<table>'; while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { echo ' <tr>'; foreach ($line as $col_value) { echo ' <td>$col_value</td>'; } echo ' </tr>'; } echo '</table>'; // 釋放結(jié)果集 mysql_free_result($result); // 關(guān)閉連接 mysql_close($link);?>extension=php_mysqli.dll
mysqli擴(kuò)展,我們有時稱之為MySQL增強(qiáng)擴(kuò)展,可以用于使用MySQL4.1.3或更新版本中新的高級特性。mysqli擴(kuò)展在PHP 5及以后版本中包含。
mysqli擴(kuò)展有一系列的優(yōu)勢,相對于mysql擴(kuò)展的提升主要有:
1. 面向?qū)ο?/u>接口2. prepared語句支持(即參數(shù)編譯預(yù)處理,可以有效防御SQL注入的發(fā)生)3. 多語句執(zhí)行支持4. 事務(wù)支持5. 增強(qiáng)的調(diào)試能力6. 嵌入式服務(wù)支持7. 在提供了面向?qū)ο蠼涌诘耐瑫r也提供了一個面向過程的接口。
mysqli擴(kuò)展是使用PHP擴(kuò)展框架構(gòu)建的,它的源代碼在PHP源碼目錄下的ext/mysqli中
<?php $con = new mysqli('localhost', 'root', '111', 'php4fun_'); /* check connection */ if (mysqli_connect_errno()) { printf('Connect failed: %s', mysqli_connect_error()); exit(); } $sql = 'select name from users where name = ? and pass = ?'; $cmd = $con->prepare($sql); $name = $_GET['name']; $pass = $_GET['pass']; //add parameters to sql query $cmd->bind_param('ss', $name, $pass); $cmd->execute(); $cmd->bind_result($result); $cmd->fetch(); if($result) { var_dump($result); }?>mysqli除了可以使用參數(shù)編譯預(yù)處理來進(jìn)行數(shù)據(jù)庫通信,同時也兼容使用面向過程的編碼方式
<?php /* Connect to a MySQL server 連接數(shù)據(jù)庫服務(wù)器 */ $link = mysqli_connect( 'localhost', /* The host to connect to 連接MySQL地址 */ 'root', /* The user to connect as 連接MySQL用戶名 */ '111', /* The password to use 連接MySQL密碼 */ 'company'); /* The default database to query 連接數(shù)據(jù)庫名稱*/ if (!$link) { printf('Can't connect to MySQL Server. Errorcode: %s ', mysqli_connect_error()); exit; } /* Send a query to the server 向服務(wù)器發(fā)送查詢請求*/ if ($result = mysqli_query($link, 'SELECT * from p8_ad_user')) { print('Very large cities are: '); /* Fetch the results of the query 返回查詢的結(jié)果 */ while( $row = mysqli_fetch_assoc($result) ) { printf('%s (%s) ', $row['Name'], $row['Population']); } /* Destroy the result set and free the memory used for it 結(jié)束查詢釋放內(nèi)存 */ mysqli_free_result($result); } /* Close the connection 關(guān)閉連接*/ mysqli_close($link); ?> PHP還支持很多其他的數(shù)據(jù)庫連接擴(kuò)展,使用方法都類似,只要遵循函數(shù)調(diào)用規(guī)范即可,更多詳情請參閱
http://www.php.net/manual/zh/refs.database.php
0x2: 使用PDO抽象層與數(shù)據(jù)庫通信
PDO(PHP 數(shù)據(jù)對象 PHP Database Object),是PHP應(yīng)用中的一個數(shù)據(jù)庫抽象層規(guī)范。PDO提供了一個統(tǒng)一的API接口可以使得你的PHP應(yīng)用不去關(guān)心具體要連接的數(shù)據(jù)庫服務(wù)器系統(tǒng) 類型。也就是說,如果你使用PDO的API,可以在任何需要的時候無縫切換數(shù)據(jù)庫服務(wù)器,比如從Firebird到MySQL,僅僅需要修改很少的PHP 代碼。
其他數(shù)據(jù)庫抽象層的例子包括Java應(yīng)用中的JDBC以及Perl中的DBI。
注意: 利用 PDO 擴(kuò)展自身并不能實現(xiàn)任何數(shù)據(jù)庫功能;必須使用一個具體數(shù)據(jù)庫的PDO驅(qū)動來訪問數(shù)據(jù)庫服務(wù)(它只是一個接口規(guī)范)
但是反過來說,一個接口提供的兼容性越強(qiáng),它的定制性、特異性就相應(yīng)越弱(這很容易理解),PDO接口API的主要缺點是會限制讓你不能使用MySQL服務(wù)端提供所有的數(shù)據(jù)庫高級特性。比如,PDO不允許使用MySQL支持的多語句執(zhí)行。
在PHP5中,PDO目前已經(jīng)支持大量數(shù)據(jù)庫,并且在PHP6中將作為默認(rèn)數(shù)據(jù)庫連接方式:
1. sqlite2. mysql3. pgsql4. mssql ...
PDO是基于PHP擴(kuò)展框架實現(xiàn)的,它的源碼在PHP源碼目錄的ext/pdo下
再次強(qiáng)調(diào),PDO只是一個接口規(guī)范,它自身并不實現(xiàn)任何的數(shù)據(jù)庫功能,程序員必須使用一個具體數(shù)據(jù)庫的'PDO驅(qū)動'來訪問特定的數(shù)據(jù)庫
extension=php_pdo_mysql.dll
<?php $dbhost='localhost'; $dbname='company'; $dbusr='root'; $dbpwd='111'; $dbhdl=NULL; $dbstm=NULL; $opt = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',); $dsn='mysql:host=' . $dbhost . ';port=3306;dbname=' . $dbname; try { $dbhdl = new PDO($dsn, $dbusr, $dbpwd, $opt); //Display exception $dbhdl->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); } catch (PDOExceptsddttrtion $e) { //return PDOException print 'Error!: ' . $e->getMessage() . '<br>'; die(); } $dbstm = $dbhdl->query('SELECT * from p8_ad_user LIMIT 0,1'); $rows = $dbstm->fetchAll(PDO::FETCH_ASSOC);//$rows = $dbhdl->Fetch(); print_r($rows);?>extension=php_pdo_pgsql.dll
<?php $host = 'localhost'; $user = 'root'; $pass = '111'; $db = 'company'; $cursor = 'cr_123456'; try { $dbh = new PDO('pgsql:host=$host;port=5432;dbname=$db;user=$user;password=$pass'); echo 'Connected<p>'; } catch (Exception $e) { echo 'Unable to connect: ' . $e->getMessage() .'<p>'; } $dbh->beginTransaction(); $query = 'SELECT * from p8_ad_user LIMIT 0,1'; $dbh->query($query); $query = 'FETCH ALL IN '$cursor''; echo 'begin data<p>'; foreach ($dbh->query($query) as $row) { echo '$row[0] $row[1] $row[2] <br>'; } echo 'end data';?>這里只以Mysql、PostGreSQL為例,事實上,PDO這種抽象層方式可以訪問目前主流的大多數(shù)的數(shù)據(jù)庫,并且PDO將成為PHP6的默認(rèn)數(shù)據(jù)庫連接方式,更多詳情請參閱
http://www.php.net/manual/zh/book.pdo.php
0x3: 使用ODBC抽象層與數(shù)據(jù)庫通信
ODBC是一種應(yīng)用程序編程接口(Application Programming Interface,API),使我們有能力連接到某個數(shù)據(jù)源(比如一個MS Access 數(shù)據(jù)庫)
試圖通過編程語言和數(shù)據(jù)庫查詢訪問(SQL標(biāo)準(zhǔn)化)來標(biāo)準(zhǔn)化連接方法,比如功能和配置。
ODBC的作用是充當(dāng)接口或連接器,它具有雙重設(shè)計目標(biāo):
1. 首先,對于ODBC 系統(tǒng),它充當(dāng)?shù)氖蔷幊陶Z言系統(tǒng)2. 其次,對于數(shù)據(jù)存儲系統(tǒng),它充當(dāng)?shù)氖?ODBC 系統(tǒng)。
所 以,ODBC 需要一個'對ODBC而言是編程語言'的驅(qū)動程序(例如PHP-ODBC庫)和一個'對數(shù)據(jù)存儲系統(tǒng)而言是ODBC'的驅(qū)動程序(比如 MySQL-ODBC庫)。除了ODBC系統(tǒng)本身之外,ODBC還可以處理數(shù)據(jù)源的配置,允許數(shù)據(jù)源和編程語言之間存在模糊性。
和之前學(xué)習(xí)的擴(kuò)展API接口、PDO略有不同的是,使用ODBC連接數(shù)據(jù)庫要稍微麻煩一點(至少我個人這么覺得),這個'麻煩'體現(xiàn)在我們需要對目標(biāo)數(shù)據(jù)庫服務(wù)器的操作系統(tǒng)進(jìn)行一些配置,即創(chuàng)建ODBC數(shù)據(jù)源,然后才可以進(jìn)行ODBC連接
創(chuàng)建到達(dá) MS Access 數(shù)據(jù)的 ODBC 連接的方法:
1. 在控制面板中打開管理工具2. 雙擊其中的數(shù)據(jù)源 (ODBC)圖標(biāo)3. 選擇系統(tǒng) DSN 選項卡4. 點擊系統(tǒng) DSN 選項卡中的'添加'按鈕5. 選擇 Microsoft Access Driver。點擊完成6. 在下一個界面,點擊“選擇”來定位數(shù)據(jù)庫7. 為這個數(shù)據(jù)庫取一個數(shù)據(jù)源名 (DSN)8. 點擊確定
code:
<html><body> <?php //連接一個ODBC數(shù)據(jù)源,無帳號、密碼 $conn = odbc_connect('northwind', '', ''); if (!$conn) { exit('Connection Failed: ' . $conn); } $sql = 'SELECT * FROM p8_ad_user'; $rs = odbc_exec($conn, $sql); if (!$rs) { exit('Error in SQL'); } echo '<table><tr>'; echo '<th>Companyname</th>'; echo '<th>Contactname</th></tr>'; while (odbc_fetch_row($rs)) { $username = odbc_result($rs, 'username'); $password = odbc_result($rs, 'password'); echo '<tr><td>$username</td>'; echo '<td>$password</td></tr>'; } odbc_close($conn); echo '</table>';?></body></html>0x4: 使用DBX與數(shù)據(jù)庫通信
PHP本身內(nèi)置了DBX函數(shù),DBX模塊是一個數(shù)據(jù)庫抽象層(DBX中的'X'就表示其所能支持的X種數(shù)據(jù)庫)。DBX函數(shù)允許你訪問所有DBX支持的數(shù)據(jù)庫。
DBX支持下列數(shù)據(jù)庫:
1. Mysql2. ODBC3. PgSQL4. Mssql(Microsoft SQL Server)5. Fbsql
download:
http://pecl.php.net/package/dbxhttp://rpmfind.net/linux/rpm2html/search.php?query=php-dbx
code:
<html><head> <title>A PHP-DBX URL Organizer</title> <style type=text/css> p, ul, td, h3, h4, h3 { font-family: verdana, helvetica, sans-serif; } </style></head><body><?/****** TABLE DEFINITION FOR THIS EXAMPLE:* create table URLS (* url VARCHAR(128) not null,* description TEXT,* primary key (url));*****///define $MODULE as DBX_MYSQL, DBX_MSSQL, DBX_PGSQL, or your supported database$MODULE = DBX_PGSQL;$server = 'localhost';$user = 'root';$password = '111';$database = 'company';/* FUNCTIONS */function get_urls($dbconn, $sql) { $result = @dbx_query($dbconn, $sql); if ( $result == 0 ) { echo dbx_error($dbconn); } else { return $result; }}function url($action, $dbconn, $url, $description) { if($action == 'add') { $sql = 'insert into URLS values('$url', '$description')'; } elseif($action == 'delete') { $url = urldecode($url); $sql = 'delete from URLS where URL = '$url''; } $result = @dbx_query($dbconn, $sql); if ( $result == 0 ) { echo '<P>ERROR ADDING URL: ' . dbx_error($dbconn); } else { print('<p>$action : $url succeeded!<p>'); }}/*** MAIN ***/$dbconn = dbx_connect($MODULE, $server, $database, $user, $password) or die('CANNOT CONNECT TO DATABASE');?><h3>PHP DBX URL Organizer</h3><form action=dbx_urls.php method=post><p><b>Add a URL:</b><br>URL: <input type='text' name='url' maxlength='128' value='http://'> Description: <input type='text' name='description'> <input type='submit' name='addurl' value='Add URL!'></form><? if(isset($addurl)) { url('add', $dbconn, $url, $description); } if(isset($delete)) { url('delete', $dbconn, $delete, ''); } $sql = 'select * from URLS'; $result = get_urls($dbconn, $sql); if(sizeof($result->data) == 0) {?><h3>Sorry, there are no URLs in the database. You should add some.<? } else {?><p><table border=1 cellpadding=5 cellspacing=0 width=600><tr><td><b>URL</b></td><td><b>Description</b></td><td> </td></tr><? for($i = 0; $i < sizeof($result->data); $i++) {?><tr><td><a href=<?=$result->data[$i]['url']?>><?=$result->data[$i]['url']?></a></td><td><?=$result->data[$i]['description']?></td><td width=1><a href=dbx_urls.php?delete=<?=urlencode($result->data[$i]['url'])?>>delete</a></tr><? }?></table><? }?></body></html>0x5: 使用DBA(Database (dbm-style) Abstraction Layer)與數(shù)據(jù)庫通信
PHP的DBA抽象層是用來支持Berkeley DB這種文件型數(shù)據(jù)庫的。
These functions build the foundation for accessing Berkeley DB style databases.
在柏克萊的BSD系列操作系統(tǒng)中,有個簡單的數(shù)據(jù)庫結(jié)構(gòu),它以數(shù)個文件組成超小型的數(shù)據(jù)庫系統(tǒng),架構(gòu)成抽象層(abstraction layer)的DBA數(shù)據(jù)庫。
目前PHP支持的DBA數(shù)據(jù)庫包括
1. DBM: 柏克萊發(fā)展的最早期DBA數(shù)據(jù)庫http://en.wikipedia.org/wiki/Dbm2. NDBM: 較新且較有彈性的DBAhttp://en.wikipedia.org/wiki/NDBM3. GDBM: GNU 發(fā)展的DBAftp://ftp.gnu.org/pub/gnu/gdbm/4. DB2: 由Sleepycat軟件開發(fā)的DB2(非IBM的DB2)http://www.openldap.org/lists/openldap-software/199905/msg00009.html5. CDB: 這是qmail作者開發(fā)快速可靠的DBAhttp://pobox.com/~djb/cdb.html
安裝好DBA后,使用如下代碼進(jìn)行連接
<?php $id = dba_open ( '/tmp/test.db' , 'n' , 'db2' ); if(! $id ) { echo 'dba_open failedn' ; exit; } dba_replace ( 'key' , 'This is an example!' , $id ); if( dba_exists ( 'key' , $id )) { echo dba_fetch ( 'key' , $id ); dba_delete ( 'key' , $id ); } dba_close ( $id ); ?>3. 后記
以上就是PHP連接數(shù)據(jù)庫的不同方式的學(xué)習(xí),通過本文的學(xué)習(xí),我們了解到一點
目前PHP開發(fā)中主流使用的連接數(shù)據(jù)庫的技術(shù)是1. Mysql擴(kuò)展API2. Mysqli擴(kuò)展API3. PDO抽象層
下一步希望做的事
1. 研究一下PHP和mysql進(jìn)行交互的協(xié)議驅(qū)動的底層原理2. 嘗試編程簡單的通信協(xié)議驅(qū)動
Copyright (c) 2014 LittleHann All rights reserved
PHP編程鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
新聞熱點
疑難解答
圖片精選