相關學習資料php
http://www.php.net/manual/zh/refs.database.php http://www.php.net/manual/zh/internals2.pdo.php http://bbs.phpchina.com/thread-184537-1-1.html http://www.metsky.com/archives/660.html http://www.phpbuilder.com/ http://www.w3school.com.cn/php/php_db_odbc.asp https://www.ibm.com/developerworks/cn/opensource/os-php-odbc/ http://blog.csdn.net/deflag/article/details/743597 http://www.informit.com/articles/article.aspx?p=31839&seqNum=3 http://zh.wikipedia.org/wiki/Berkeley_DB http://blog.csdn.net/zuiaituantuan/article/details/5996376
目錄css
1. PHP數據庫驅動簡介 2. PHP鏈接數據庫的不一樣方式
1. PHP數據庫驅動簡介html
驅動是一段設計用來於一種特定類型的數據庫服務器進行交互的軟件代碼。驅動可能會調用一些庫。相似於Java中的數據庫驅動的概念mysql
1. JDBC-ODPC橋: 它將JDBC API映射到ODPC API。再讓JDBC-ODPC調用數據庫本地驅動代碼(也就是數據庫廠商提供的數據庫操做二進制代碼庫,例如Oracle中的oci.dll) 2. 本地API驅動 直接將JDBC API映射成數據庫特定的客戶端API,即經過客戶端加載數據庫廠商提供的本地代碼庫(C/C++等) 3. 網絡協議驅動(主流) 這種類型的驅動給客戶端提供了一個網絡API,客戶端上的JDBC驅動程序使用套接字(Socket)來調用服務器上的中間件程序,後者在將其請求轉化爲所需的具體API調用。 4. 本地協議驅動(主流) 這種類型的驅動使用Socket,直接在客戶端和數據庫間通訊。它是一種直接與數據庫實例交互的JDBC 這種驅動是智能的,它知道數據庫使用的底層協議,也是目前最主流使用的JDBC驅動,咱們本章的重點就是它
而對於PHP來講,一樣主流使用的也是網絡協議驅動、本地協議驅動,即MySQL客戶端庫、MySQL Native驅動庫。 這些庫實現了用於和MySQL數據庫服務器進行交互的底層協議。
數據庫驅動位於PHP和數據庫進行通訊的最底層,不一樣的數據庫廠商都會在基於某個框架的前提下實現本身的驅動,用以提供基本功能、以及特定數據庫的高級功能。linux
在驅動層之上是"鏈接器"、或者是適配器抽象層,用於PHP代碼和數據庫進行鏈接,程序員可使用PDO(PHP Database Object)、或者直接使用擴展接口(mysql、mysqli)這些暴露出來的API與底層數據庫進行通訊。程序員
數據庫廠商提供的底層數據庫驅動sql
mysql: http://www.mysql.com/products/connector/ oracle: http://www.oracle.com/technetwork/indexes/downloads/index.html#database sqlserver: http://msdn.microsoft.com/zh-cn/library/cc296170(SQL.90).aspx
...
文件型數據庫數據庫
文件型是一種基於文件的數據庫引擎,並且使用文件I/O(輸入/輸出)函數來存儲和讀取來自磁盤上文件的數據庫。它廣泛也比關係型數據庫(例如Mysql)小不少不少(例如典型的文件型數據庫
SQLite命令行版本的大小小於200KB),同時,文件型數據庫並且支持你所熟悉的大部分SQL命令,同時具備易於攜帶的特色
接下來,咱們以上面這張大圖做爲開始,逐一學習PHP鏈接數據庫的不一樣方式、以及它們在不一樣業務場景下的優缺點編程
2. PHP鏈接數據庫的不一樣方式服務器
0x1: 使用擴展API接口與數據庫通訊
PHP代碼是由一個核心,一些可選擴展組成了核心功能。PHP 的MySQL相關擴展,好比mysqli,mysql都是基於PHP擴展框架實現的。
擴 展一個典型的做用就是暴露一個API給PHP程序員,容許擴展本身的功能能夠被程序員使用。固然,也有一部分基於PHP擴展框架 開發的擴展不會給PHP程序員暴露API接口。好比說PDO MySQL驅動擴展,就沒有向PHP程序員暴露API接口,可是向它上層的PDO層提供了一個接口。
關於PHP擴展的編寫請參閱另外一篇博文 http://www.cnblogs.com/LittleHann/p/3562259.html
在實際編程中,使用頻度最多的仍是以擴展API的方式去鏈接數據庫
extension=php_mysql.dll
這 是設計開發容許PHP應用與MySQL數據庫交互的早期擴展。mysql擴展提供了一個面向過程的接口,而且是針對MySQL4.1.3或更早版本設計 的。所以,這個擴展雖然能夠與MySQL4.1.3或更新的數據庫服務端 進行交互,但並不支持後期MySQL服務端提供的一些特性
mysql擴展的源代碼在PHP擴展目錄ext/mysql下
<?php // 鏈接、選擇數據庫 $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'); // 執行 SQL 查詢 $query = 'SELECT * FROM my_table'; $result = mysql_query($query) or die('Query failed: ' . mysql_error()); // 以 HTML 打印查詢結果 echo "<table>\n"; while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { echo "\t<tr>\n"; foreach ($line as $col_value) { echo "\t\t<td>$col_value</td>\n"; } echo "\t</tr>\n"; } echo "</table>\n"; // 釋放結果集 mysql_free_result($result); // 關閉鏈接 mysql_close($link); ?>
extension=php_mysqli.dll
mysqli擴展,咱們有時稱之爲MySQL加強擴展,能夠用於使用MySQL4.1.3或更新版本中新的高級特性。mysqli擴展在PHP 5及之後版本中包含。
mysqli擴展有一系列的優點,相對於mysql擴展的提高主要有:
1. 面向對象接口 2. prepared語句支持(即參數編譯預處理,能夠有效防護SQL注入的發生) 3. 多語句執行支持 4. 事務支持 5. 加強的調試能力 6. 嵌入式服務支持 7. 在提供了面向對象接口的同時也提供了一個面向過程的接口。
mysqli擴展是使用PHP擴展框架構建的,它的源代碼在PHP源碼目錄下的ext/mysqli中
<?php $con = new mysqli("localhost", "root", "111", "php4fun_"); /* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", 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除了可使用參數編譯預處理來進行數據庫通訊,同時也兼容使用面向過程的編碼方式
<?php /* Connect to a MySQL server 鏈接數據庫服務器 */ $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 鏈接數據庫名稱*/ if (!$link) { printf("Can't connect to MySQL Server. Errorcode: %s ", mysqli_connect_error()); exit; } /* Send a query to the server 向服務器發送查詢請求*/ if ($result = mysqli_query($link, 'SELECT * from p8_ad_user')) { print("Very large cities are: "); /* Fetch the results of the query 返回查詢的結果 */ while( $row = mysqli_fetch_assoc($result) ) { printf("%s (%s) ", $row['Name'], $row['Population']); } /* Destroy the result set and free the memory used for it 結束查詢釋放內存 */ mysqli_free_result($result); } /* Close the connection 關閉鏈接*/ mysqli_close($link); ?>
PHP還支持不少其餘的數據庫鏈接擴展,使用方法都相似,只要遵循函數調用規範便可,更多詳情請參閱
http://www.php.net/manual/zh/refs.database.php
0x2: 使用PDO抽象層與數據庫通訊
PDO(PHP 數據對象 PHP Database Object),是PHP應用中的一個數據庫抽象層規範。PDO提供了一個統一的API接口可使得你的PHP應用不去關心具體要鏈接的數據庫服務器系統 類型。也就是說,若是你使用PDO的API,能夠在任何須要的時候無縫切換數據庫服務器,好比從Firebird到MySQL,僅僅須要修改不多的PHP 代碼。
其餘數據庫抽象層的例子包括Java應用中的JDBC以及Perl中的DBI。
注意: 利用 PDO 擴展自身並不能實現任何數據庫功能;必須使用一個具體數據庫的PDO驅動來訪問數據庫服務(它只是一個接口規範)
可是反過來講,一個接口提供的兼容性越強,它的定製性、特異性就相應越弱(這很容易理解),PDO接口API的主要缺點是會限制讓你不能使用MySQL服務端提供全部的數據庫高級特性。好比,PDO不容許使用MySQL支持的多語句執行。
在PHP5中,PDO目前已經支持大量數據庫,而且在PHP6中將做爲默認數據庫鏈接方式:
1. sqlite 2. mysql 3. pgsql 4. mssql ...
PDO是基於PHP擴展框架實現的,它的源碼在PHP源碼目錄的ext/pdo下
再次強調,PDO只是一個接口規範,它自身並不實現任何的數據庫功能,程序員必須使用一個具體數據庫的"PDO驅動"來訪問特定的數據庫
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這種抽象層方式能夠訪問目前主流的大多數的數據庫,而且PDO將成爲PHP6的默認數據庫鏈接方式,更多詳情請參閱
http://www.php.net/manual/zh/book.pdo.php
0x3: 使用ODBC抽象層與數據庫通訊
ODBC是一種應用程序編程接口(Application Programming Interface,API),使咱們有能力鏈接到某個數據源(好比一個MS Access 數據庫)
試圖經過編程語言和數據庫查詢訪問(SQL標準化)來標準化鏈接方法,好比功能和配置。
ODBC的做用是充當接口或鏈接器,它具備雙重設計目標:
1. 首先,對於ODBC 系統,它充當的是編程語言系統 2. 其次,對於數據存儲系統,它充當的是 ODBC 系統。
所 以,ODBC 須要一個"對ODBC而言是編程語言"的驅動程序(例如PHP-ODBC庫)和一個"對數據存儲系統而言是ODBC"的驅動程序(好比 MySQL-ODBC庫)。除了ODBC系統自己以外,ODBC還能夠處理數據源的配置,容許數據源和編程語言之間存在模糊性。
和以前學習的擴展API接口、PDO略有不一樣的是,使用ODBC鏈接數據庫要稍微麻煩一點(至少我我的這麼以爲),這個"麻煩"體如今咱們須要對目標數據庫服務器的操做系統進行一些配置,即建立ODBC數據源,而後才能夠進行ODBC鏈接
建立到達 MS Access 數據的 ODBC 鏈接的方法:
1. 在控制面板中打開管理工具 2. 雙擊其中的數據源 (ODBC)圖標 3. 選擇系統 DSN 選項卡 4. 點擊系統 DSN 選項卡中的"添加"按鈕 5. 選擇 Microsoft Access Driver。點擊完成 6. 在下一個界面,點擊「選擇」來定位數據庫 7. 爲這個數據庫取一個數據源名 (DSN) 8. 點擊肯定
code:
<html> <body> <?php //鏈接一個ODBC數據源,無賬號、密碼 $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與數據庫通訊
PHP自己內置了DBX函數,DBX模塊是一個數據庫抽象層(DBX中的"X"就表示其所能支持的X種數據庫)。DBX函數容許你訪問全部DBX支持的數據庫。
DBX支持下列數據庫:
1. Mysql 2. ODBC 3. PgSQL 4. Mssql(Microsoft SQL Server) 5. Fbsql
download:
http://pecl.php.net/package/dbx http://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, h1, h2, 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"); ?> <h1>PHP DBX URL Organizer</h1> <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)與數據庫通訊
PHP的DBA抽象層是用來支持Berkeley DB這種文件型數據庫的。
These functions build the foundation for accessing Berkeley DB style databases.
在柏克萊的BSD系列操做系統中,有個簡單的數據庫結構,它以數個文件組成超小型的數據庫系統,架構成抽象層(abstraction layer)的DBA數據庫。
目前PHP支持的DBA數據庫包括
1. DBM: 柏克萊發展的最先期DBA數據庫 http://en.wikipedia.org/wiki/Dbm 2. NDBM: 較新且較有彈性的DBA http://en.wikipedia.org/wiki/NDBM 3. GDBM: GNU 發展的DBA ftp://ftp.gnu.org/pub/gnu/gdbm/ 4. DB2: 由Sleepycat軟件開發的DB2(非IBM的DB2) http://www.openldap.org/lists/openldap-software/199905/msg00009.html 5. CDB: 這是qmail做者開發快速可靠的DBA http://pobox.com/~djb/cdb.html
安裝好DBA後,使用以下代碼進行鏈接
<?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鏈接數據庫的不一樣方式的學習,經過本文的學習,咱們瞭解到一點
目前PHP開發中主流使用的鏈接數據庫的技術是 1. Mysql擴展API 2. Mysqli擴展API 3. PDO抽象層
下一步但願作的事
1. 研究一下PHP和mysql進行交互的協議驅動的底層原理 2. 嘗試編程簡單的通訊協議驅動
Copyright (c) 2014 LittleHann All rights reserved