PDO 增删改查

Selecting Data

PDO 增删改查_第1张图片

你在mysql_*中是这样做的


    $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'];
    }

或者


    $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 对象,如果你想取出结果,请这样使用:


    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(),比如说:


    $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

PDO 增删改查_第2张图片

在mysql_*中我们是这样做的


    $results = mysql_query("UPDATE table SET field='value'") or die(mysql_error());
    echo mysql_affected_rows($result);

在PDO中,同样可以这样:

$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 工作流:

  1. Prepare: 语句(statement)模版被application创建,发送到数据库管理系统(DBMS)。某些值仍然违背置顶,通过参数、占位符进行绑定
INSERT INTO PRODUCT (name, price) VALUES (?, ?)
  1. DBMS进行解析、编译,得到最优的语句,把结果(语句)储存起来,并不执行。

  2. 执行。过后,程序为参数提供或绑定值,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

  1. 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);
  1. insert
$stmt = $db->prepare("INSERT INTO table(field1,field2) VALUES(:field1,:field2)");
$stmt->execute(array(':field1' => $field1, ':field2' => $field2));
$affected_rows = $stmt->rowCount();
  1. delete
$stmt = $db->prepare("DELETE FROM table WHERE id=:id");
$stmt->bindValue(':id', $id, PDO::PARAM_STR);
$stmt->execute();
$affected_rows = $stmt->rowCount();
  1. 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
高翔翻译。
转载请注明原文和译文链接谢谢。

你可能感兴趣的:(StackOverflow,PHP)