PHP數(shù)據(jù)庫驅(qū)動擴(kuò)展概述與不同方式連接數(shù)據(jù)庫總結(jié)

極客小俊
?一個(gè)專注于web技術(shù)的80后
你不用拼過聰明人,你只需要拼過那些懶人 你就一定會超越大部分人!

主要說兩個(gè)方面
PHP數(shù)據(jù)庫驅(qū)動的簡介
PHP連接數(shù)據(jù)庫的不同方式案例比較
PHP數(shù)據(jù)庫驅(qū)動簡介
這里的驅(qū)動是指的一段特定類型的數(shù)據(jù)庫服務(wù)器進(jìn)行交互的軟件代碼。驅(qū)動可能會調(diào)用一些庫。類似于Java中的數(shù)據(jù)庫驅(qū)動的概念
其實(shí)也就是數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫操作二進(jìn)制代碼庫!
例如: Oracle中的oci.dll、
PHP數(shù)據(jù)庫驅(qū)動
數(shù)據(jù)庫驅(qū)動位于PHP和數(shù)據(jù)庫進(jìn)行通信的最底層,這一層就是數(shù)據(jù)庫驅(qū)動層, 不同的數(shù)據(jù)庫廠商都會在基于某個(gè)框架的前提下實(shí)現(xiàn)自己的驅(qū)動,用以提供基本功能、以及特定數(shù)據(jù)庫的高級功能
PHP連接器
在數(shù)據(jù)庫驅(qū)動層之上是 連接器、或者叫適配器抽象層,或者通俗點(diǎn)叫連接層、用于PHP代碼和數(shù)據(jù)庫進(jìn)行連接,
比如PHP開發(fā)者可以使用PDO(PHP Database Object)、或者直接使用擴(kuò)展接口(mysql、mysqli) 這些暴露出來的API函數(shù)來與底層數(shù)據(jù)庫進(jìn)行通信。
數(shù)據(jù)庫驅(qū)動層、連接器 、PHP代碼應(yīng)用層 圖如下

小知識:文件類型數(shù)據(jù)庫
?文件型是一種基于文件的數(shù)據(jù)庫引擎,而且使用文件I/O(輸入/輸出)函數(shù)來存儲和讀取來自磁盤上文件的數(shù)據(jù)庫。
?它普遍也比關(guān)系型數(shù)據(jù)庫(例如Mysql)小很多! (例如典型的文件型數(shù)據(jù)庫SQLite命令行版本的大小小于200KB)
?同時(shí),文件型數(shù)據(jù)庫支持你所熟悉的大部分SQL命令,同時(shí)具有易于攜帶的特點(diǎn)
PHP連接數(shù)據(jù)庫的不同方式、以及不同業(yè)務(wù)場景下的優(yōu)缺點(diǎn)
1.使用擴(kuò)展API接口與數(shù)據(jù)庫通信
PHP代碼是由一些可選擴(kuò)展組成的核心功能
PHP 的MySQL數(shù)據(jù)庫相關(guān)擴(kuò)展,比如mysqli,mysql都是基于PHP擴(kuò)展框架實(shí)現(xiàn)的
這些擴(kuò)展的作用就是暴露一個(gè)API給PHP程序員, 允許擴(kuò)展自己的功能可以被程序員使用
當(dāng)然,也有一部分基于PHP擴(kuò)展框架 開發(fā)的擴(kuò)展不會給PHP程序員暴露API接口。 比如說PDO MySQL驅(qū)動擴(kuò)展,就沒有向PHP程序員暴露API接口,但是向它上層的PDO層提供了一個(gè)接口
在實(shí)際編程中,使用頻度最多的還是以擴(kuò)展API的方式去連接數(shù)據(jù)庫
mysql擴(kuò)展
小伙伴是不是經(jīng)常修改php.ini文件的時(shí)候看見了extension=php_mysql.dll 這個(gè)東西呢 它就是一個(gè)mysql擴(kuò)展,
這是開發(fā)時(shí)允許PHP應(yīng)用與MySQL數(shù)據(jù)庫交互的早期擴(kuò)展 , mysql擴(kuò)展提供了一個(gè)面向過程的接口,并且是針對MySQL4.1.3或更早版本設(shè)計(jì)的。
mysql擴(kuò)展的位置是在早期的5.x版本的PHP目錄下的ext/mysql.dll
因此,這個(gè)擴(kuò)展雖然可以與MySQL4.1.3或更新的數(shù)據(jù)庫服務(wù)端進(jìn)行交互,但并不支持后期最新的MySQL服務(wù)端提供的一些特性以及功能, 所以后來大家在現(xiàn)在的php7.x當(dāng)中就看不見mysql.dll這個(gè)擴(kuò)展了 被官方取消了!
######
? //連接數(shù)據(jù)庫
? ? ?$link = mysql_connect('主機(jī)地址', '數(shù)據(jù)庫用戶名', '密碼') or die('Could not connect: ' . mysql_error());
? ? ?echo 'Connected successfully';
?
? //選擇數(shù)據(jù)庫
? ? ?mysql_select_db('數(shù)據(jù)庫名稱') or die('錯誤信息');
?
? ? ?// 執(zhí)行 SQL 查詢
? ? ?$query = 'SELECT * FROM 表名稱';
? ? ?$result = mysql_query($query) or die('錯誤信息' . mysql_error());
?
? ? ?// 以 HTML 打印查詢結(jié)果
?
? ? ?echo "<table>\n";
?
? //循環(huán)的從結(jié)果集當(dāng)中一條一條的獲取數(shù)據(jù) 渲染遍歷輸出!
? ? ?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";
?
? ? ?//釋放結(jié)果集
? ? ?mysql_free_result($result);
?
? ? ?//關(guān)閉連接
? ? ?mysql_close($link);
mysqli擴(kuò)展
mysqli擴(kuò)展,我們有時(shí)稱之為MySQL增強(qiáng)擴(kuò)展,可以用于使用MySQL4.1.3或更新版本中新的高級特性, 所以大家能夠在php7.x的ext擴(kuò)展目錄中找到php_mysqli.dll 這個(gè)擴(kuò)展, ?mysqli擴(kuò)展在PHP 5及以后版本中都會包含!
mysqli擴(kuò)展有一系列的優(yōu)勢,相對于mysql擴(kuò)展的提升主要有如下:
?. 面向?qū)ο蠼涌??可以理解成有面向?qū)ο蟮姆绞絹頃鴮懘a
?. prepared語句支持(即參數(shù)編譯預(yù)處理,可以有效防御SQL注入的發(fā)生)
?. 多語句執(zhí)行支持
?. 事務(wù)支持
?. 增強(qiáng)的調(diào)試能力
?. 嵌入式服務(wù)支持
?. 在提供了面向?qū)ο蠼涌诘耐瑫r(shí)也提供了一個(gè)面向過程的接口。
所以這也大大提高了開發(fā)者的可選擇性. 和性能的優(yōu)越性
mysqli擴(kuò)展是使用PHP擴(kuò)展框架構(gòu)建的,它的在PHP目錄下的ext/mysqli.dll中
使用案例
? ?$con = new mysqli("數(shù)據(jù)庫主機(jī)名", "用戶名", "密碼", "數(shù)據(jù)庫名稱");
? ? ?/* check connection */
?
? ? ? //判斷返回的值是否大于0 大于0就說明有錯誤 ?
? ? ?if (mysqli_connect_errno())
? ? ?{
? ? ? ? ?printf("Connect failed: %s\n", mysqli_connect_error());
? ? ? ? ?exit();
? ? ?}
?
? //預(yù)處理SQL
? ? ?$sql = "select name from users where name = ? and pass = ?";
? ? ?$cmd = $con->prepare($sql);
?
? //接收數(shù)據(jù)
? ? ?$name = $_GET['name'];
? ? ?$pass = $_GET['pass'];
?
? ? ?//向sql查詢添加綁定參數(shù)
? ? ?$cmd->bind_param("ss", $name, $pass);
?
? //執(zhí)行準(zhǔn)備好的預(yù)處理查詢語句
? ? ?$cmd->execute();
?
? //將變量綁定到準(zhǔn)備好的語句以進(jìn)行結(jié)果存儲, 其實(shí)就是拿一個(gè)變量來保存結(jié)果
? ? ?$cmd->bind_result($result);
?
? //將準(zhǔn)備好的語句的結(jié)果提取到綁定變量中
? ? ?$cmd->fetch();
?
? //判斷結(jié)果是否已經(jīng)存在? 存在就打印出來
? ? ?if($result)
? ? ?{
? ? ? ? ?var_dump($result);
? ? ?}
mysqli除了可以使用參數(shù)編譯預(yù)處理來進(jìn)行數(shù)據(jù)庫的信息通信交互,同時(shí)也兼容使用面向過程的編碼方式
這個(gè)就看開發(fā)者的個(gè)人習(xí)慣而定了 你喜歡這么使用就怎么使用
使用案例
? /* ?連接數(shù)據(jù)庫服務(wù)器 */ ?
? ? ?$link = mysqli_connect( ?
? ? ? ? ? ? ? ? ?'連接MySQL地址', ? ? /* The host to connect to 連接MySQL地址 */ ?
? ? ? ? ? ? ? ? ?'用戶名', ? ? ? ? ? /* The user to connect as 連接MySQL用戶名 */ ?
? ? ? ? ? ? ? ? ?'密碼', ? ? /* The password to use 連接MySQL密碼 */ ?
? ? ? ? ? ? ? ? ?'連接數(shù)據(jù)庫名稱'); ? ?/* The default database to query 連接數(shù)據(jù)庫名稱*/ ?
? ? ? ?
? //判斷是否成功 失敗輸出失敗錯誤代碼
? ? ?if (!$link)
? ? ?{ ?
? ? ? ? ?printf("Can't connect to MySQL Server. Errorcode: %s ", mysqli_connect_error()); ?
? ? ? ? ?exit; ?
? ? ?} ?
? ? ? ?
? ? ?/* 向服務(wù)器發(fā)送查詢SQL語句請求*/ ?
? ? ?if ($result = mysqli_query($link, 'SELECT * from 表名稱'))
? ? ?{ ? ?
? ? ? ? ?/* 返回查詢的結(jié)果 并遍歷結(jié)果集 一條一條的循環(huán)遍歷輸出 */ ?
? ? ? ? ?while( $row = mysqli_fetch_assoc($result) )
? ? ? ? ?{ ?
? ? ? ? ? ? ?printf("%s (%s) ", $row['字段名'], $row['字段名']); ?
? ? ? ? ?} ?
? ? ? ?
? ? ? ? ?/* 結(jié)束查詢釋放內(nèi)存*/ ?
? ? ? ? ?mysqli_free_result($result); ?
? ? ?} ?
? ? ? ?
? ? ?/* 關(guān)閉連接*/ ?
? ? ?mysqli_close($link); ?
PHP還支持很多其他的數(shù)據(jù)庫連接擴(kuò)展,使用方法都類似,只要遵循函數(shù)調(diào)用規(guī)范即可!
更多詳情參考官方文檔: ?https://www.php.net/manual/zh/refs.database.php
2.使用PDO抽象層與數(shù)據(jù)庫通信
PDO中文簡稱數(shù)據(jù)對象, 英文全稱:PHP Database Object
PDO數(shù)據(jù)庫訪問抽象層是統(tǒng)一各種數(shù)據(jù)庫的訪問接口、是PHP應(yīng)用中的一個(gè)數(shù)據(jù)庫抽象層規(guī)范
PDO提供了一個(gè)統(tǒng)一的API接口, 可以使得你的PHP應(yīng)用不去關(guān)心具體要連接的數(shù)據(jù)庫服務(wù)器系統(tǒng)類型
通俗點(diǎn)說, 也就是如果你使用PDO的API,可以在任何需要的時(shí)候 無縫切換數(shù)據(jù)庫服務(wù)器,比如從Firebird到MySQL,僅僅需要修改很少的PHP 代碼就可以辦到! 是不是很方便呢 ?
小提示: 利用 PDO 擴(kuò)展自身并不能實(shí)現(xiàn)任何數(shù)據(jù)庫功能, 注意是功能! 必須使用一個(gè)具體數(shù)據(jù)庫的PDO驅(qū)動來訪問想要的數(shù)據(jù)庫服務(wù)(它只是一個(gè)接口規(guī)范)
但是一個(gè)接口提供的兼容性越強(qiáng),它的定制性、特異性就相應(yīng)越弱(這個(gè)應(yīng)該不難理解吧)
PDO接口API的主要缺點(diǎn)是會限制讓你不能使用MySQL服務(wù)端提供所有的數(shù)據(jù)庫高級特性。
比如,PDO不允許使用MySQL支持的多語句執(zhí)行, 如下圖

在PHP5中,PDO目前已經(jīng)支持大量數(shù)據(jù)庫, 例如
?1. sqlite
?2. mysql
?3. pgsql
?4. mssql
?...
PDO是基于PHP擴(kuò)展框架實(shí)現(xiàn)的,它的源碼在PHP目錄的ext/php_pdo_*
再一次強(qiáng)調(diào),PDO只是一個(gè)接口規(guī)范,它自身并不實(shí)現(xiàn)任何的數(shù)據(jù)庫功能,開發(fā)者必須使用一個(gè)具體數(shù)據(jù)庫的"PDO驅(qū)動"來訪問特定的數(shù)據(jù)庫
php_pdo_mysql擴(kuò)展
PDO連接MySQL要在php.ini中的配置參數(shù)是: extension=php_pdo_mysql.dll ?這個(gè)配置必須要打開才能連接MySQL服務(wù)
基本使用案例如下
? ? ?$dbhost="主機(jī)名";
? ? ?$dbname="數(shù)據(jù)庫名稱";
? ? ?$dbusr="用戶名";
? ? ?$dbpwd="密碼";
? ? ?$dbhdl=NULL;
? ? ?$dbstm=NULL;
?
? //連接數(shù)據(jù)庫參數(shù)配置
? ? ?$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);
? ? ? ? ?//設(shè)置屬性 ?錯誤報(bào)告 和 錯誤拋出異常
? ? ? ? ?$dbhdl->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
? ? ?}
? ? ?catch (PDOExceptsddttrtion $e)
? ? ?{
? ? ? ? ?//return PDOException
? ? ? ? ?print "Error!: " . $e->getMessage() . "<br>";
? ? ? ? ?die();
? ? ?}
?
? // 執(zhí)行SQL語句,將結(jié)果集作為PDOStatement對象返回
? ? ?$dbstm = $dbhdl->query('SELECT * from p8_ad_user LIMIT 0,1');
?
? //從包含的結(jié)果集當(dāng)中取出所有行并且返回?cái)?shù)組
? ? ?$rows = $dbstm->fetchAll(PDO::FETCH_ASSOC);//也可以使用$rows = $dbhdl->Fetch();
? //打印結(jié)果
? ? ?print_r($rows);
?
?
php_pdo_pgsql擴(kuò)展
extension=php_pdo_pgsql.dll
PDO連接PostgreSQL 要在php.ini中的配置參數(shù)是: extension=php_pdo_pgsql.dll ?這個(gè)配置必須要打開才能連接PostgreSQL 服務(wù)
這個(gè)其實(shí)我也沒怎么常用!
基本使用案例如下
? ? ?$host = "主機(jī)地址";
? ? ?$user = "用戶名";
? ? ?$pass = "密碼";
? ? ?$db = "數(shù)據(jù)庫名稱";
? ? ?$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();
? ? ?
? //執(zhí)行查詢
? ? ?$query = "SELECT * from p8_ad_user LIMIT 0,1";
? ? ?$dbh->query($query);
? ? ?$query = "FETCH ALL IN \"$cursor\"";
?
? ? ?echo "begin data<p>";
? ? ?//遍歷結(jié)果
? ? ?foreach ($dbh->query($query) as $row)
? ? ?{
? ? ? ? ?echo "$row[0] $row[1] $row[2] <br>";
? ? ?} ?
? ? ?echo "end data";
這里只簡單的說一說Mysql、PostGreSQL的案例,事實(shí)上,PDO這種抽象層方式可以訪問目前主流的大多數(shù)的數(shù)據(jù)庫
3.使用ODBC抽象層與數(shù)據(jù)庫通信
ODBC基本介紹
ODBC在PHP的手冊上基本上都全是英文的 所以對一些英文不好的小白可能不太友好 ,在這里我也簡單的說一下
ODBC的英文全稱 (Open Database Connectivity) 是一種開放數(shù)據(jù)庫互連 也就是一個(gè)應(yīng)用程序編程接口(Application Programming Interface,簡稱API),使我們有能力連接到某個(gè)數(shù)據(jù)源、它為編寫關(guān)系數(shù)據(jù)庫的客戶軟件提供了一種統(tǒng)一的接口。
使用ODBC API 的應(yīng)用程序可以與任何具有ODBC驅(qū)動程序的關(guān)系數(shù)據(jù)庫進(jìn)行通信、
ODBC 是為客戶應(yīng)用程序訪問關(guān)系數(shù)據(jù)庫時(shí)提供的一個(gè)標(biāo)準(zhǔn)的接口、對于不同的數(shù)據(jù)庫,ODBC 提供了統(tǒng)一的 API,使用該 API 來訪問任何提供了 ODBC 驅(qū)動程序的數(shù)據(jù)庫
圖解如下

總的來說和之前說的擴(kuò)展API接口、PDO抽象層 略有不同,使用ODBC連接數(shù)據(jù)庫要稍微麻煩一點(diǎn)
使用ODBC需要對目標(biāo)數(shù)據(jù)庫服務(wù)器的操作系統(tǒng)進(jìn)行一些配置,即創(chuàng)建ODBC數(shù)據(jù)源,然后才可以進(jìn)行ODBC連接, 就如同上面的圖中 我們要在接口驅(qū)動程序管理器中配置ODBC數(shù)據(jù)源, 比如我們要使用ODBC連接MySQL就要先安裝MySQL的ODBC驅(qū)動程序!
MySQL ODBC驅(qū)動安裝和配置數(shù)據(jù)源
第一步
驅(qū)動程序下載地址https://dev.mysql.com/downloads/connector/odbc/
選擇適合自己電腦版本(我的操作系統(tǒng)是Win10,64位)

進(jìn)入下載界面后,我們不登錄(Login)也不注冊(Sign Up)。直接點(diǎn)左下角的【No thanks,just start my download.】即可開始下載。

下載完安裝包后,雙擊打開安裝包,按照默認(rèn)選項(xiàng)進(jìn)行安裝即可。
第二步
配置數(shù)據(jù)源
打開控制面板\所有控制面板項(xiàng)\管理工具\(yùn)ODBC 數(shù)據(jù)源

在控制面板下的管理工具,找到ODBC數(shù)據(jù)源后 雙擊打開

?在【用戶DSN】選項(xiàng)卡中單擊【添加】按鈕,然后選擇MySQL ODBC 8.0 Unicode Driver ?單擊完成!

注意 :這里要說明一下“MYSQL ODBC 8.0 ANSI Driver”和“MySQL ODBC 8.0 Unicode Driver”的區(qū)別: ①M(fèi)ySQL ODBC 8.0 ANSI Driver 只針對有限的字符集的范圍; ②MySQL ODBC 8.0 Unicode Driver 提供了更多字符集的支持,也就是提供了多語言的支持
單擊完成后會彈出填寫配置信息對話框 前兩個(gè)選項(xiàng)可根據(jù)項(xiàng)目功能信息填寫, 然后按具體情況填寫TCP/IP Server和Port, 然后是MySQL用戶名、密碼、數(shù)據(jù)庫名稱。

Data Source Name: ? //數(shù)據(jù)源名稱,可自擬(最好跟項(xiàng)目功能掛鉤) Description: ? ? ? //關(guān)于此數(shù)據(jù)源的描述,主要功能等,可不填寫 TCP/IP Server: ? ? //服務(wù)器名稱,可以是機(jī)器名,也可以是IP地址;若是本地可填寫“l(fā)ocalhost” Port: ? ? ? ? ? ? ?//MySQL服務(wù)的端口號,默認(rèn)是3306,也可在安裝MySQL時(shí)自己設(shè)定 User: ? ? ? ? ? ? ?//用戶名,默認(rèn)是root,也可在安裝MySQL時(shí)自己設(shè)定 Password: ? ?//密碼 Database: ? ?//數(shù)據(jù)庫名稱
填寫完后可點(diǎn)擊【Test】按鈕,測試一下連接是否配置成功!如果成功會有連接成功的提示!

若測試成功,再點(diǎn)擊 OK 按鈕即可!在用戶DSN處即可查看到最新創(chuàng)建的ODBC

到這里就配置好了 MySQL ODBC驅(qū)動程序了
PHP用ODBC連接MySQL
首先檢查PHP目錄下的php.ini中,extension=odbc 擴(kuò)展是否打開!
代碼案例如下:
$dsn="Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=shop;charset=utf8"; $conn_odbc = odbc_connect($dsn, "root", "密碼"); //如果SQL命令執(zhí)行成功,則返回ODBC結(jié)果標(biāo)識符 $row = odbc_do($conn_odbc,"SELECT * FROM test4"); //獲取數(shù)據(jù)總條數(shù) $odbc_num_rows = odbc_num_rows($row); echo "找到記錄數(shù)量:".$odbc_num_rows; echo "<br>"; //從標(biāo)識當(dāng)中判斷是否有行 if (odbc_fetch_row($row)){ ? ? //獲取結(jié)果數(shù)據(jù) ? ? echo '名稱:'.odbc_result($row,"brand"); ? ? echo '<br>'; ? ? echo '顏色:'.odbc_result($row,"color"); }
特別注意: 編碼的一定要統(tǒng)一!
總結(jié)
差不多了吧。。以上就是PHP連接數(shù)據(jù)庫的不同方式
目前PHP開發(fā)中主流使用的連接數(shù)據(jù)庫的技術(shù)是?
1. Mysqli擴(kuò)展API?
2. PDO抽象層
如果喜歡話請 點(diǎn)贊 ?投幣 ?收藏 一鍵三連 ?
大家的支持就是我堅(jiān)持下去的動力!
不要忘了?? 關(guān)注 ??哦!
