目前共有67篇帖子。 字體大小:較小 - 100% (默認)▼  內容轉換:大陆简体▼
 
點擊 回復
4837 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)
 

本帖信息

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