目前共有67篇帖子。 內容轉換:不轉換▼
 
點擊 回復
2432 66
今天我來系統地學習一下PDO
一派護法 十九級
1樓 發表于:2015-5-30 19:22
操作系統:Fedora 21
PHP版本:最新的5.6.9
開發工具:gedit
一派護法 十九級
2樓 發表于:2015-5-30 19:23
本帖負責收集筆記。
一派護法 十九級
3樓 發表于:2015-5-30 19:25
<?php
include_once("conn.php");
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>PDO Learning</title>
</head>
 
<body>
<?php  
 
?>
</body>
</html>

最基本的HTML5頁面代碼,好難記。。。
一派護法 十九級
4樓 發表于:2015-5-30 19:26
回復:3樓
不過也比HTML4好記多了。
HTML4一上來就是:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
一派護法 十九級
5樓 發表于:2015-5-30 19:28
首先,連接數據庫。
$db = new PDO("mysql:host=localhost;dbname=test", "php", "it");
密碼先填寫一個錯誤的,提示:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user 'php'@'localhost' (using password: YES)' in /var/www/html/temp/11330/conn.php:4 Stack trace: #0 /var/www/html/temp/11330/conn.php(4): PDO->__construct('mysql:host=loca...', 'php', 'it') #1 /var/www/html/temp/11330/index.php(2): include_once('/var/www/html/t...') #2 {main} thrown in /var/www/html/temp/11330/conn.php on line 4
所以必須要加try-catch塊來處理這個錯誤
一派護法 十九級
6樓 發表于:2015-5-30 19:29
一派護法 十九級
7樓 發表于:2015-5-30 19:32
function display_exception($msg) {
    echo $msg;
}
set_exception_handler("display_exception");
$db = new PDO("mysql:host=localhost;dbname=test", "php", "it");

exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user 'php'@'localhost' (using password: YES)' in /var/www/html/temp/11330/conn.php:8 Stack trace: #0 /var/www/html/temp/11330/conn.php(8): PDO->__construct('mysql:host=loca...', 'php', 'it') #1 /var/www/html/temp/11330/index.php(2): include_once('/var/www/html/t...') #2 {main}
一派護法 十九級
8樓 發表于:2015-5-30 19:33
try {
    $db = new PDO("mysql:host=localhost;dbname=test", "php", "it");
} catch (PDOException $e) {
    echo $e->getMessage();
}

SQLSTATE[HY000] [1045] Access denied for user 'php'@'localhost' (using password: YES)
一派護法 十九級
9樓 發表于:2015-5-30 19:39
try {
    $db = new PDO("mysql:host=localhost;dbname=test", "php", "it");
} catch (PDOException $e) {
    trigger_error("Failed connecting to the database server.", E_USER_ERROR);
}

Fatal error: Failed connecting to the database server. in /var/www/html/temp/11330/conn.php on line 7

UTC+12:00
張樹人
中級工程師 十級
10樓 發表于:2015-5-30 19:39
回復:3樓
標準的寫法是「<!DOCTYPE html>」
「DOCTYPE」是大寫
一派護法 十九級
11樓 發表于:2015-5-30 19:39
try {
    $db = new PDO("mysql:host=localhost;dbname=test", "php", "it");
} catch (PDOException $e) {
    trigger_error($e->getMessage(), E_USER_ERROR);
}

Fatal error: SQLSTATE[HY000] [1045] Access denied for user 'php'@'localhost' (using password: YES) in /var/www/html/temp/11330/conn.php on line 7

一派護法 十九級
12樓 發表于:2015-5-30 19:40

回復:10樓

DWCS3中自動生成的代碼就是這樣。

一派護法 十九級
13樓 發表于:2015-5-30 19:40

回復:11樓

以後一般情況下都採用這個代碼

一派護法 十九級
14樓 發表于:2015-5-30 19:42
接下來研究如何建立持久連接,這個我還從來沒學過。。。
一派護法 十九級
15樓 發表于:2015-5-30 19:43
PHP手冊上說,建立數據庫持久連接可以大幅度提高性能。
一派護法 十九級
16樓 發表于:2015-5-30 19:43
資料庫!
不是數據庫(大陸說法)!
一派護法 十九級
17樓 發表于:2015-5-30 19:57
$dbh = null;
這個相當於原來的mysql_close();
一派護法 十九級
18樓 發表于:2015-5-30 19:58
人家官方文檔都用$dbh,所以我也用$dbh吧。。。
一派護法 十九級
19樓 發表于:2015-5-30 20:01
try {
    $dbh = new PDO("mysql:host=localhost;dbname=test", "php", DB_PW, array(PDO::ATTR_PERSISTENT => true));
} catch (PDOException $e) {
    trigger_error($e->getMessage(), E_USER_ERROR);
}

// NO OUTPUT
一派護法 十九級
20樓 發表于:2015-5-30 20:05
PDO::ATTR_PERSISTENT
mysql:host=localhost;dbname=test
這兩個需要記住
一派護法 十九級
21樓 發表于:2015-5-30 20:53
獲取單條記錄

$id = (int)@$_GET["i"];
if ($id < 1) {
    $id = 1;
}
$sql = "SELECT ItemName, ItemAddress FROM WiFiHotSpots WHERE ItemID = {$id}";
$stmt = $dbh->query($sql); // use $stmt instead of $rs or $result
$row = $stmt->fetch();
echo "<b>" . $row[0] . "</b>: " . $row["ItemAddress"];

輸出: 7th Brigade Park, Chermside: Delaware St
一派護法 十九級
22樓 發表于:2015-5-30 20:55
獲取多條記錄,並循環邊歷記錄集
<?php
$sql = "SELECT ItemName, ItemAddress FROM WiFiHotSpots";
$stmt = $dbh->query($sql); // use $stmt instead of $rs or $result
foreach ($stmt as $row) {
    echo "<p><b>" . $row[0] . "</b>: " . $row["ItemAddress"]."</p>";
}
?>
一派護法 十九級
23樓 發表于:2015-5-30 21:00
循環邊歷記錄集可以用多種方法:
方法一:foreach ($stmt as $row) {
方法二:while ($row = $stmt->fetch()) {

甚至還可以指定次數:
for ($i = 0; $i < 4 && $row = $stmt->fetch(); $i++) {
    echo "<p><b>" . $row[0] . "</b>: " . $row["ItemAddress"]."</p>";
}
一派護法 十九級
24樓 發表于:2015-5-30 21:01
while ($row = $stmt->fetch()) {
就相當於原來的:
while ($row = mysql_fetch_array($rs)) {

for ($i = 0; $i < 4 && $row = $stmt->fetch(); $i++) {
相當於
for ($i = 0; $i < 4 && $row = mysql_fetch_array($rs); $i++) {
一派護法 十九級
25樓 發表于:2015-5-30 21:03
foreach ($stmt as $row) { 只能遍歷整個記錄集,要想指定次數就得改用$row = $stmt->fetch();
一派護法 十九級
26樓 發表于:2015-5-30 21:11
從外部獲取字符串參數並傳入SQL查詢中:
<?php
if (isset($_GET["name"])) {
    $name = trim($_GET["name"]); // 去掉字符串兩邊的空格
    $name = $dbh->quote($name); // 這個大致相當於原來的用於防止SQL隱碼攻擊的mysql_real_escape_string函數,但是這個函數兩邊自動加上了單引號
    //echo $name;
} else {
    $name = "Annerley Library Wifi";
}
$sql = "SELECT * FROM WiFiHotSpots WHERE ItemName = {$name}"; //注意不能再加單引號了
$stmt = $dbh->query($sql);
$row = $stmt->fetch();
echo "(" . $row["ItemLatitude"] . ", " . $row["ItemLongitude"] . ")";
?>

輸出(-27.3739664, 153.078323)
一派護法 十九級
27樓 發表于:2015-5-30 21:15
回復:26樓
看PHP官方文檔下面的內容吧:
PDO::quote() places quotes around the input string (if required) and escapes special characters within the input string, using a quoting style appropriate to the underlying driver.
If you are using this function to build SQL statements, you are strongly recommended to use PDO::prepare() to prepare SQL statements with bound parameters instead of using PDO::quote() to interpolate user input into an SQL statement. Prepared statements with bound parameters are not only more portable, more convenient, immune to SQL injection, but are often much faster to execute than interpolated queries, as both the server and client side can cache a compiled form of the query.
Not all PDO drivers implement this method (notably PDO_ODBC). Consider using prepared statements instead.
因此26樓所屬的方法機不推薦使用,應該改用prepare+bind+execute方法。
一派護法 十九級
28樓 發表于:2015-5-30 21:16
而且,不是所有數據庫都兼容$dbh->quote
一派護法 十九級
29樓 發表于:2015-5-30 21:19
改進後的26樓代碼:
if (isset($_GET["name"])) {
    $name = trim($_GET["name"]);
} else {
    $name = "Annerley Library Wifi";
}

$sql = "SELECT * FROM WiFiHotSpots WHERE ItemName = ?";
$stmt = $dbh->prepare($sql);
$stmt->execute(array($name));
$row = $stmt->fetch();
echo "(" . $row["ItemLatitude"] . ", " . $row["ItemLongitude"] . ")";
一派護法 十九級
30樓 發表于:2015-5-30 21:20
注意,那個?同樣不能再加單引號

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:2432 回複數:66
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2015-5-31 12:24
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。