本文主要介紹了詳解PHP中的PDO類,PDO類可以幫助人們更方便地在PHP中使用資料庫。希望對大家使用PDO有幫助。
簡介
咱一起來看看PDO類別。 PDO是PHP Data Objects的縮寫,它被描述為「在PHP中存取資料庫的輕量級,相容性的介面」。儘管它的名字不好聽,但PDO是一個在PHP中存取資料庫會讓人喜愛的方式。
與MySQLi的不同
MySQLi和PDO很相似,都有兩個面向主要差異:
1.MySQLi只能存取MySQL,但PDO可以存取12種不同的資料庫
2.PDO沒有普通函數呼叫(mysqli_*functions)
開始步驟
#首先,你得確定一下你的PHP是否安裝了PDO外掛。你可以用$test=new PDO()的結果來測試。如果提示說是參數不匹配,那證明已經安裝了PDO插件,如果說是物件不存在,你得先確認一下在pho.ini中php_pdo_yourssqlserverhere.extis是否被註解掉了。如果沒有這句話,那你得安裝PDO了,這裡就不囉嗦了。
連接
現在我們確認伺服器已經運作,開始連接資料庫:
$dsn = 'mysql:dbname=demo;host=localhost;port=3306'; $username = 'root'; $password = 'password_here'; try { $db = new PDO($dsn, $username, $password); // also allows an extra parameter of configuration } catch(PDOException $e) { die('Could not connect to the database:<br/>' . $e); }
除$dsn之外,所有語句和變數都能自我解釋。 DSN指的是資料來源名稱,有多種輸入類型。最常見的一種是我們剛剛使用的這種,PHP官網解釋了 其他可用的DSN 。
你可以省去DSN的其他額外參數,只需要在資料庫驅動後面帶個冒號,例如(mysql:)。在這種情況下PDO將會嘗試連線到本機資料庫。就像當你使用MySQLi時需要在查詢中指定資料庫名稱一樣。
最後一件你需要注意的事情就是我們用try-catch區塊包裹了我們的初始化物件。 PDO連線失敗的時候將會拋出PDOException異常而不是查詢失敗的時候。如果你願意你可以使用下面程式碼$db=line來選擇異常的模式。
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
或你可以直接在PDO初始化時傳遞參數:
$db = new PDO($dsn, $username, $password, array ( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ));
我們現在使用的是錯誤的方式-在失敗時候簡單回傳false,我們是沒有理由不對例外進行處理的。
基本查詢
在PDO中使用query和exec兩種方法使得對資料庫查詢變得非常簡單。如果你想要得到查詢結果的行數exec是非常好用的,因此對SELECT查詢語句是非常有用的。
現在我們透過下面的一個例子來查看這兩個方法:
$statement = <<<SQL SELECT * FROM `foods` WHERE `healthy` = 0 SQL; $foods = $db->query($statement);
行數
echo $foods->rowCount();
#遍歷結果集
列印出這些可口的食物一點也不困難:
foreach($foods->FetchAll() as $food) { echo $food['name'] . '<br />'; }
轉義用戶輸入(的特殊字元)
$input: this is's' a '''pretty dange'rous str'ing
$db->quote($input): 'this is\'s\' a \'\'\'pretty dange\'rous str\'ing' exec()
$statement = <<<SQL DELETE FROM `foods` WHERE `healthy` = 1; SQL; echo $db->exec($statement); // outputs number of deleted rows
預處理語句
儘管exec方法和查詢在PHP中仍然被大量使用和支持,但是PHP官網上還是要求大家用預處理語句的方式來替代。為什麼呢?主要是因為:它比較安全。預處理語句不會直接在實際查詢中插入參數,這避免了許多潛在的SQL注入。 然而出於某種原因,PDO實際上並沒有真正的使用預處理,它是在模擬預處理方式,在將語句傳給SQL伺服器之前會把參數資料插入到語句中,這使得某些系統容易受到SQL注入。如果你的SQL服务器不真正的支持预处理,我们可以很容易的通过如下方式在PDO初始化时传参来修复这个问题:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
接下来开始我们的第一个预处理语句吧:
$statement = $db->prepare('SELECT * FROM foods WHERE `name`=? AND `healthy`=?'); $statement2 = $db->prepare('SELECT * FROM foods WHERE `name`=:name AND `healthy`=:healthy)';
正如你所见,有两种创建参数的方法,命名的与匿名的(不可以同时出现在一个语句中)。然后你可以使用bindValue来敲进你的输入:
$statement->bindValue(1, 'Cake'); $statement->bindValue(2, true); $statement2->bindValue(':name', 'Pie'); $statement2->bindValue(':healthy', false);
注意使用命名参数的时候你要包含进冒号(:)。PDO还有一个bindParam方法,可以通过引用绑定数值,也就是说它只在语句执行的时候查找相应数值。
现在剩下的唯一要做的事情,就是执行我们的语句:
$statement->execute(); $statement2->execute(); // Get our results: $cake = $statement->Fetch(); $pie = $statement2->Fetch();
为了避免只使用bindValue带来的代码碎片,你可以用数组给execute方法作为参数,像这样:
$statement->execute(array(1 => 'Cake', 2 => true)); $statement2->execute(array(':name' => 'Pie', ':healthy' => false));
事务
前面我们已经描述过了什么是事务:
一个事务就是执行一组查询,但是并不保存他们的影响到数据库中。这样做的好处是如果你执行了4条相互依赖的插入语句,当有一条失败后,你可以回滚使得其他的数据不能够插入到数据库中,确保相互依赖的字段能够正确的插入。你需要确保你使用的数据库引擎支持事务。
开启事务
你可以很简单的使用beginTransaction()方法开启一个事务:
$db->beginTransaction(); $db->inTransaction(); // true!
然后你可以继续执行你的数据库操作语句,在最后提交事务:
$db->commit();
还有类似MySQLi中的rollBack()方法,但是它并不是回滚所有的类型(例如在MySQL中使用DROP TABLE),这个方法并不是真正的可靠,我建议尽量避免依赖此方法。
其他有用的选项
有几个选项你可以考虑用一下。这些可以作为你的对象初始化时候的第四个参数输入。
$options = array($option1 => $value1, $option[..]); $db = new PDO($dsn, $username, $password, $options);
PDO::ATTR_DEFAULT_FETCH_MODE
你可以选择PDO将返回的是什么类型的结果集,如PDO::FETCH_ASSOC,会允许你使用$result['column_name'],或者PDO::FETCH_OBJ,会返回一个匿名对象,以便你使用$result->column_name
你还可以将结果放入一个特定的类(模型),可以通过给每一个单独的查询设置一个读取模式,就像这样:
$query = $db->query('SELECT * FROM `foods`'); $foods = $query->fetchAll(PDO::FETCH_CLASS, 'Food');
- 所有读取模式
上面我们已经解释过这一条了,但喜欢TryCatch的人需要用到:PDO::ERRMODE_EXCEPTION。如果不论什么原因你想抛出PHP警告,就使用PDO::ERRMODE_WARNING。
PDO::ATTR_TIMEOUT
当你为载入时间而着急时,你可以使用此属性来为你的查询指定一个超时时间,单位是秒. 注意,如果超过你设置的时间,缺省会抛出E_WARNING异常, 除非 PDO::ATTR_ERRMODE 被改变.
更多属性信息可以在 PHP官网的属性设置 里查看到.
最后的思考
PDO是一个在PHP中访问你的数据库的很棒的方式,可以认为是最好的方式。除非你拒绝使用面向对象的方法或是太习惯 MySQLi 的方法名称,否则没有理由不使用PDO。
更好的是完全切换到只使用预处理语句,这最终将使你的生活更轻松!
相关推荐:
以上是PHP之詳解PDO的詳細內容。更多資訊請關注PHP中文網其他相關文章!