十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
水城網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),水城網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為水城超過千家提供企業(yè)網(wǎng)站建設(shè)服務。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個售后服務好的水城做網(wǎng)站的公司定做!
使用PDO在與不同數(shù)據(jù)庫管理系統(tǒng)之間交互時,PDO對象中的成員方法是統(tǒng)一各種數(shù)據(jù)庫的訪問接口,所以在使用PDO與數(shù)據(jù)庫進行交互之前,首先要創(chuàng)建一個PDO對象。在通過構(gòu)造方法創(chuàng)建對象的同時,需要建立一個與數(shù)據(jù)庫服務器的連接,并選擇一個數(shù)據(jù)庫
PDO的構(gòu)造方法原型如下
__construct ( string $dsn [,string $username [,string $password [,array $driver_options ]]] )
在構(gòu)造方法中,第一個必選的參數(shù)是數(shù)據(jù)源名(dsn),用來定義一個確定的數(shù)據(jù)庫和必須用到的驅(qū)動程序。DSN的PDO命名慣例為PDO驅(qū)動程序的名稱,后面為一個冒號,再后面是可選的驅(qū)動程序的數(shù)據(jù)庫連接變量信息,如主機名、端口和數(shù)據(jù)庫名
構(gòu)造方法中的第二個參數(shù)username和第三個參數(shù)password分別指定用于連接數(shù)據(jù)庫的用戶名和密碼。最后一個參數(shù)driver_options需要一個數(shù)組,用來指定連接所需的所有額外選項,傳遞附加的調(diào)優(yōu)參數(shù)到PDO或底層驅(qū)動程序

/*連接如果失敗,使用異常處理模式進行捕獲 */$dsn = 'MySQL:dbname=pdotest;host=127.0.0.1'; //連接MySQL數(shù)據(jù)庫的DSN $user = 'root'; //MySQL數(shù)據(jù)庫的用戶名$password = '*****'; //MySQL數(shù)據(jù)庫的密碼try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo '數(shù)據(jù)庫連接失?。?nbsp;' . $e->getMessage();
}
在創(chuàng)建PDO對象時,有一些與數(shù)據(jù)庫連接相關(guān)的選項,可以將必要的幾個選項組成數(shù)據(jù)傳遞給構(gòu)造方法的第四個參數(shù)driver_opts中,用來傳遞附加的調(diào)優(yōu)參數(shù)到PDO或底層驅(qū)動程序

PDO::ATTR_AUTOCOMMIT): PDO是否關(guān)閉自動提交功能 PDO::ATTR_ERRMODE): 當前PDO的錯誤處理的模式 PDO::ATTR_CASE): 表字段字符的大小寫轉(zhuǎn): PDO::ATTR_CONNECTION_STATUS): 與連接狀態(tài)相關(guān)特有信息: PDO::ATTR_ORACLE_NULLS): 空字符串轉(zhuǎn)換為SQL的null PDO::ATTR_PERSISTENT): 應用程序提前獲取數(shù)據(jù)大 PDO::ATTR_SERVER_INFO): 與數(shù)據(jù)庫特有的服務器信 PDO::ATTR_SERVER_VERSION): 數(shù)據(jù)庫服務器版本號信息 PDO::ATTR_CLIENT_VERSION): 數(shù)據(jù)庫客戶端版本號信息


//設(shè)置持久連接的選項數(shù)組作為最后一個參數(shù),可以一起設(shè)置多個元素 $opt = array(PDO::ATTR_PERSISTENT => true);
try {
$db = new PDO('mysql:dbname=pdotest;host=127.0.0.1','root','*****',$opt);
} catch (PDOException $e) {
echo "數(shù)據(jù)庫連接失?。?nbsp;" .$e->getMessage();
}
調(diào)整PDO的行為屬性
在PDO對象中有很多屬性用來調(diào)整PDO的行為或獲取底層驅(qū)動程序狀態(tài)。如果在創(chuàng)建PDO對象時,沒有在構(gòu)造方法中最后一個參數(shù)過屬性選項,也可以在對象創(chuàng)建完成之后,通過PDO對象中的setAttribute()和getAttribute()方法設(shè)置和獲取這些屬性的值
PDO::getAttribute()
PDO::getAttribute()用于取回一個數(shù)據(jù)庫連接的屬性
mixed PDO::getAttribute ( int $attribute )
PDO::setAttribute()
PDO::setAttribute()用于設(shè)置屬性
bool PDO::setAttribute ( int $attribute , mixed $value )

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);//$dbh->setAttribute(3,2); $dbh->setAttribute(PDO::ATTR_AUTOCOMMIT,0);//$dbh->setAttribute(0,0); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);//$dbh->setAttribute(19,2); echo "\nPDO是否關(guān)閉自動提交功能:". $dbh->getAttribute(PDO::ATTR_AUTOCOMMIT);echo "\n當前PDO的錯誤處理的模式:". $dbh->getAttribute(PDO::ATTR_ERRMODE); echo "\n表字段字符的大小寫轉(zhuǎn)換: ". $dbh->getAttribute(PDO::ATTR_CASE); echo "\n與連接狀態(tài)相關(guān)特有信息: ". $dbh->getAttribute(PDO::ATTR_CONNECTION_STATUS); echo "\n空字符串轉(zhuǎn)換為SQL的null:". $dbh->getAttribute(PDO::ATTR_ORACLE_NULLS); echo "\n應用程序提前獲取數(shù)據(jù)大小:".$dbh->getAttribute(PDO::ATTR_PERSISTENT); echo "\n與數(shù)據(jù)庫特有的服務器信息:".$dbh->getAttribute(PDO::ATTR_SERVER_INFO); echo "\n數(shù)據(jù)庫服務器版本號信息:". $dbh->getAttribute(PDO::ATTR_SERVER_VERSION);echo "\n數(shù)據(jù)庫客戶端版本號信息:". $dbh->getAttribute(PDO::ATTR_CLIENT_VERSION);

錯誤處理
PDO一共提供了三種不同的錯誤處理模式,不僅可以滿足不同風格的編程,也可以調(diào)整擴展處理錯誤的方式
PDO:ERRORMODE_SILENT
這是默認模式,在錯誤發(fā)生時不進行任何操作,PDO將只設(shè)置錯誤代碼。開發(fā)人員可以通過PDO對象中的errorCode()和errorInfo()方法對語句和數(shù)據(jù)庫對象進行檢查。如果錯誤是由于對語句對象的調(diào)用而產(chǎn)生的,那么可以在那個語句對象上調(diào)用errorCode()或errorInfo()方法。如果錯誤是由于調(diào)用數(shù)據(jù)庫對象而產(chǎn)生的,那么可以在那個數(shù)據(jù)庫對象上調(diào)用上述兩個方法
PDO:ERRMODE_WARNING
除了設(shè)置錯誤代碼以外,PDO還將發(fā)出一條PHP傳統(tǒng)的E_WARNING消息,可以使用常規(guī)的PHP錯誤處理程序捕獲該警告。如果只是想看看發(fā)生了什么問題,而無意中斷應用程序的流程,那么在調(diào)試或測試中這種設(shè)置很有用
$dbh->setAttrbute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);//設(shè)置警告模式處理錯誤
PDO:ERRMODE_EXCEPTION
除了設(shè)置錯誤代碼以外,PDO還將拋出一個PDOException,并設(shè)置其屬性,以反映錯誤代碼和錯誤信息。這種設(shè)置在調(diào)試中也很有用,因為它會放大腳本中產(chǎn)生錯誤的地方,從而可以非??焖俚刂赋龃a中有問題的潛在區(qū)域。異常模式另一個有用的地方是,與傳統(tǒng)的PHP風格的警告相比,可以更清晰地構(gòu)造自己的錯誤處理,而且,比起以寂靜方式及顯式檢查每個數(shù)據(jù)庫調(diào)用的返回值,異常模式代碼及嵌套代碼也更少
$dbh->setAttrbute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);//設(shè)置異常模式處理錯誤
執(zhí)行SQL語句
在使用PDO執(zhí)行查詢數(shù)據(jù)之前,先提供一組相關(guān)的數(shù)據(jù)。創(chuàng)建PDO對象并通過mysql驅(qū)動連接mysql數(shù)據(jù)庫服務器,創(chuàng)建一個以'testdb'命名的數(shù)據(jù)庫,并在該數(shù)據(jù)庫中創(chuàng)建一個聯(lián)系人信息表contactInfo

CREATE TABLE contactInfo( uid MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, departmentID CHAR(3) NOT NULL, address VARCHAR(80) NOT NULL, phone VARCHAR(20), email VARCHAR(20), PRIMARY KEY(uid) );

數(shù)據(jù)表contactInfo建立之后,向表中插入多行記錄
INSERT INTO contactInfo(name,departmentID,address,phone,email) VALUES ('張三','D01','朝陽','15011111234','zs@aaa.com'),('李四','D02','朝陽','15011112345','ls@aaa.com'),('王五','D02','海淀','15011113456','ww@aaa.com'),('趙四','D01','海淀','15011114567','zx@aaa.com');
PDO::exec()
PDO::exec()函數(shù)執(zhí)行一條SQL語句,并返回受影響的行數(shù)
int PDO::exec ( string $statement )
當執(zhí)行INSERT、UPDATE、DELETET等沒有結(jié)果集的查詢時,使用PDO對象中的exec()方法去執(zhí)行。該方法成功執(zhí)行后,將返回受影響的行數(shù)

getMessage(); exit;
}$query = "UPDATE contactInfo SET phone='12345678900' WHERE name='張三'";$affected = $dbh->exec($query);if($affected){ //數(shù)據(jù)表contactInfo中受影響的行數(shù)為:1
echo '數(shù)據(jù)表contactInfo中受影響的行數(shù)為:' .$affected;
}else{ print_r($dbh->errorInfo());
}$query = "UPDATE contactInfo SET phone='123456789' WHERE (uid%2 = 0)";$affected = $dbh->exec($query);if($affected){ //數(shù)據(jù)表contactInfo中受影響的行數(shù)為:2
echo '數(shù)據(jù)表contactInfo中受影響的行數(shù)為:' .$affected;
}else{ print_r($dbh->errorInfo());
}?>

PDO::lastInsertId()
PDO::lastInsertId()函數(shù)用于返回最后插入行的ID或序列值
string PDO::lastInsertId ([ string $name = NULL ] )

getMessage(); exit;
}try{ $query = "INSERT INTO contactInfo(name,departmentID,phone,email) VALUES ('諸葛','D03','120120120','zg@aaa.com')"; $affected = $dbh->exec($query);
echo $affected."
";//1
echo $dbh->lastInsertId();//5}catch(PDOException $e){ echo "錯誤:" .$e->getMessage();
}?>

PDO::query()
當執(zhí)行返回結(jié)果集的SELECT查詢時,或者所影響的行數(shù)無關(guān)緊要時,應當使用PDO對象中的query()方法。如果該方法成功執(zhí)行指定的查詢,則返回一個PDOStatement對象。如果使用了query()方法,并想了解獲取的數(shù)據(jù)行總數(shù),可以使用PDOStatement對象中的rowCount()方法獲取
PDOStatement::rowCount()
PDOStatement::rowCount()函數(shù)返回受上一個 SQL 語句影響的行數(shù)
int PDOStatement::rowCount ( void )

getMessage(); exit;
}$query = "SELECT name,phone,email FROM contactInfo WHERE departmentId='D01'";try{ $pdostatement = $dbh->query($query);
echo "一共從表中獲取到".$pdostatement->rowCount()."條記錄:
"; foreach($pdostatement as $row){ echo $row['name'] ."\t"; echo $row['phone'] ."\t"; echo $row['email'] ."
";
}
}catch (PDOException $e){ echo $e->getMessage();
}?>

事務是確保數(shù)據(jù)庫一致的機制,是一個或一系列的查詢,作為一個單元的一組有序的數(shù)據(jù)庫操作。如果組中的所有SQL語句都操作成功,則認為事務成功,事務則被提交,其修改將作用于所有其他數(shù)據(jù)庫進程。即使在事務的組中只有一個環(huán)節(jié)操作失敗,事務也不成功,則整個事務將被回滾,該事務中所有操作都被取消。事務功能是企業(yè)級數(shù)據(jù)庫的一個重要部分,因為很多業(yè)務過程都包括多個步驟。如果任何一個步驟失敗,則所有步驟都不應發(fā)生。事務處理有4個特征:原子性(Atomicity)、一致性(Consistency)、獨立性(Isolation)和持久性(Durability),即ACID。對于在一個事務中執(zhí)行的任何工作,即使它是分階段進行的,也一定可以保證該工作會安全地應用于數(shù)據(jù)庫,并且在工作被提交時,不會受到其他連接的影響
MySQL目前只有InnoDB和BDB兩個數(shù)據(jù)庫表類型才支持事務,兩個表類型具有相同的特性,InnoDB表類型具有比BDB還豐富的特性,速度更快,因此建議使用InnoDB表類型。創(chuàng)建InnoDB類型的表實際上與創(chuàng)建任何其他類型表的過程沒有區(qū)別,如果數(shù)據(jù)庫沒有設(shè)置為默認的表類型,只要在創(chuàng)建時顯式指定要將表創(chuàng)建為InnoDB類型
要實現(xiàn)事務處理,首先要使用InnoDB引擎
ALTER TABLE contactInfo engine=innodb;

在默認的情況下,MySQL是以自動提交(autocommit)模式運行的,這就意味著所執(zhí)行的每一個語句都將立即寫入數(shù)據(jù)庫中。但如果使用事務安全的表格類型,是不希望有自動 提交的行為的,所以要在當前的會話中關(guān)閉自動提交
SET AUTOCOMMIT = 0;//在當前的會話中關(guān)閉自動提交
如果提交被打開了,必須開啟一個事務;如果自動提交是關(guān)閉的,則不需要使用這條命令,因為輸入一個SQL命令時,一個事務將自動啟動
START TRANSACTION;//開啟一個事務
在完成了一組事務的語句輸入后,需要提交一個事務,該事務才能在其他會話中被其他用戶所見
COMMIT;//提交一個事務給數(shù)據(jù)庫
如果改變注意,可以回滾到以前的狀態(tài)
ROOLBACK;//事務被回滾,所有操作都被取消
事務處理完成后,再次開啟自動提交
SET AUTOCOMMIT = 1;

下面在PHP中進行事務處理操作,對張三和李四進行部門交換來輪崗培養(yǎng)

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //關(guān)閉自動提交
$dbh-> setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
}catch(PDOException $e) { echo "數(shù)據(jù)庫連接失?。?.$e->getMessage(); exit;
}try { //開啟一個事務
$dbh -> beginTransaction(); $affected_rows = $dbh->exec("UPDATE contactInfo set departmentID = 'D02' where uid=1"); if($affected_rows > 0) { echo "張三轉(zhuǎn)崗成功!
";
} else { throw new PDOException("張三轉(zhuǎn)崗失敗!
");
} $affected_rows = $dbh-> exec("UPDATE contactInfo set departmentID = 'D01' where uid=2"); if($affected_rows) { echo "李四轉(zhuǎn)崗成功!
";
}else { throw new PDOException("李四轉(zhuǎn)崗失??!
");
} echo "輪崗成功!
"; //提交以上的操作
$dbh->commit();
}catch(PDOException $e) { echo "錯誤:".$e->getMessage(); echo "轉(zhuǎn)崗失敗!
"; //撤銷所有操作
$dbh -> rollback();
}//運行完成以后, 最后開啟自動提交$dbh-> setAttribute(PDO::ATTR_AUTOCOMMIT, 1);?>
