Selecting Data
你在mysql_*中是这样做的
<?php
$result = mysql_query('SELECT * from table') or die(mysql_error()); $num_rows = mysql_num_rows($result); while($row = mysql_fetch_assoc($result)) { echo $row['field1'];
}
你在pdo中可以这个样
<?php $stmt = $db->query('SELECT * FROM table'); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['field1'];
}
或者
<?php
$result = mysql_query('SELECT * from table') or die(mysql_error()); $num_rows = mysql_num_rows($result); while($row = mysql_fetch_assoc($result)) { echo $row['field1'];
}
提示:如果你使用了方法像query()。这个方法返回一个PDOStatement 对象,如果你想取出结果,请这样使用:
<?php
foreach($db->query('SELECT * FROM table') as $row) { echo $row['field1'];
}
PDO数据是通过->fetch() 方法获得的,这个方法是你的statement处理的。
在fetch之前。最好告诉PDO这个数据你打算怎么fetch。在下个章节我会解释。
Fetch Modes
PDO::FETCH_ASSOC 可以在fetch() 和 fetchAll()中使用。 这个告诉PDO返回关联数组,字段的名字作为key。这还有很多fench方法。
首先我说明怎么选择fench 模式。
$stmt->fetch(PDO::FETCH_ASSOC)
在这里我用的是fetch,你也可以用:
- PDOStatement::fetchAll() 返回了一个数组包含了所有选择的行
- PDOStatement::fetchColumn() 返回下一行的一列作为结果集
- PDOStatement::fetchObject() 返回下一行作为一个对象
- PDOStatement::setFetchMode() 设置fetch模式
下面讨论fetch模式
- PDO::FETCH_ASSOC 关联数组
- PDO::FETCH_BOTH 默认的。返回关联数组和索引数组。
还有更多选项,可以阅读文档。
获取行的数量
不是通过mysql_num_rows 而是通过rowCount(),比如说:
<?php
$stmt = $db->query('SELECT * FROM table'); $row_count = $stmt->rowCount(); echo $row_count.' rows selected';
获取插入的id
<?php $result = $db->exec("INSERT INTO table(firstname, lastname) VAULES('John', 'Doe')"); $insertId = $db->lastInsertId();
Insert and Update or Delete statements
在mysql_*中我们是这样做的
<?php
$results = mysql_query("UPDATE table SET field='value'") or die(mysql_error()); echo mysql_affected_rows($result);
在PDO中,同样可以这样:
<?php $affected_rows = $db->exec("UPDATE table SET field='value'"); echo $affected_rows;
在上面的语句中,执行了一个sql语句并且返回受影响的行数。
上面的方法在你查询语句中没有变量时很好用。如果有变量,就应该使用 prepared statement or parameterized statement 。
Prepared Statements
Q:什么是 Prepared Statements,我为什么要用他?
A:Prepared Statement 是一条预编译的sql语句,可以被执行多次。
典型的使用Prepared Statement 工作流:
- Prepare: 语句(statement)模版被application创建,发送到数据库管理系统(DBMS)。某些值仍然违背置顶,通过参数、占位符进行绑定
INSERT INTO PRODUCT (name, price) VALUES (?, ?)
DBMS进行解析、编译,得到最优的语句,把结果(语句)储存起来,并不执行。
执行。过后,程序为参数提供或绑定值,DBMS执行语句(一般会返回一个结果)。程序或许会执行多次因为它有不同的值,想获得不同的结果。咱这个例子里,把Bread作为第一个参数,1.00作为第二个参数。
你可以通过引入占位符使用预编译语句。
Q:什么是命名占位符(named placeholders ),怎么使用呢?
A:命名占位符,用过一个冒号而不是? 这样就不用去操心问号的顺序问题了
$stmt->bindParam(':bla', $bla);
<?php $stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name"); $stmt->execute(array(':name' => $name, ':id' => $id)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
另一个对于OOP(面向对象编程)很友好的就是,命名占位符可以直接插入到你的对象,再然后加入到你的数据库。假设属性与字段相同
class person {
public $name; public $add; function __construct($a,$b) {
$this->name = $a; $this->add = $b;
}
}$demo = new person('john','29 bla district');$stmt = $db->prepare("INSERT INTO table (name, add) value (:name, :add)");$stmt->execute((array)$demo);
Q:好了,什么是匿名占位符(unnamed placeholders),怎么使用?
A:看个例子。
<?php $stmt = $db->prepare("INSERT INTO folks (name, add) values (?, ?)"); $stmt->bindValue(1, $name, PDO::PARAM_STR); $stmt->bindValue(2, $add, PDO::PARAM_STR); $stmt->execute();
$stmt = $db->prepare("INSERT INTO folks (name, add) values (?, ?)"); $stmt->execute(array('john', '29 bla district'));
注意:在匿名占位符我们一定要注意在数组中的顺序,在PDOStatement::execute() 方法中。
SELECT, INSERT, UPDATE, DELETE prepared queries
- select
$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");$stmt->execute(array(':name' => $name, ':id' => $id));$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- insert
$stmt = $db->prepare("INSERT INTO table(field1,field2) VALUES(:field1,:field2)");$stmt->execute(array(':field1' => $field1, ':field2' => $field2));$affected_rows = $stmt->rowCount();
- delete
$stmt = $db->prepare("DELETE FROM table WHERE id=:id");$stmt->bindValue(':id', $id, PDO::PARAM_STR);$stmt->execute();$affected_rows = $stmt->rowCount();
- update
$stmt = $db->prepare("UPDATE table SET name=? WHERE id=?");$stmt->execute(array($name, $id));$affected_rows = $stmt->rowCount();
注意:
PDO和Mysqli也不是完全的安全。有机会会翻译一遍这个文章,这里就简单说一下:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$pdo->query('SET NAMES GBK');$stmt = $pdo->prepare("SELECT * FROM test WHERE name = ? LIMIT 1");$stmt->execute(array(chr(0xbf) . chr(0x27) . " OR 1=1 /*"));
翻译自http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php