personnages

PDO 对象常用方法

PDO 对象方法

方法描述
exec()执行一条 SQL 语句,并返回其受影响的行数,如果没有受影响的行数则返回 0
query()执行一条 SQL 语句,返回一个 PDOStatement 对象
prepare()准备要执行的 SQL 语句,返回 PDOStatement 对象
quote()返回一个添加引号的字符串,用于 SQL 语句中
lastInertId返回最后插入的行的ID
setAttribute()设置数据库连接属性
getAttribute()获取数据库连接属性
errorCode()获取跟数据库句柄上一次操作相关的 SQLSTATE
errorInfo()获取跟数据库句柄上一次操作的错误信息

PDOStatement 对象方法

方法描述
execute()执行一条预处理语句
rowCount()返回上一个 SQL 语句影响的行数
fetch()从结果集中获取一行
fetchAll()返回一个包含结果集中所有行的数组
setFetchMode()为语句设置默认的获取模式
fetchColumn()从结果集下一行返回单独的行
fetchObject()获取下一行并作为一个对象返回
bindParam()绑定一个参数到指定的变量名
bindValue()把一个值绑定到一个参数
bindColumn()绑定一列到一个 PHP 变量
getColumnMeta()返回结果集中一列的元数据
columnCount()返回结果集中的列数
setAttribute()设置一个语句属性
getAttribute获取一个语句属性
errorCode()获取跟上一个语句句柄操作相关的SQLSTATE
errorInfo()获取跟上一个语句句柄操作相关的拓展错误信息
debugDumpParams()打印一条 SQL 预处理命令
nextRowset()在一个多行集语句句柄中推进到下一个行集

exec() 方法

exec() 写入

exec() 方法可以用来执行数据库的 INSERTUPDATEDELETE操作。并且不支持 SELECT 相关操作

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"));
    // 建表 SQL
    $sql = <<<EOF
        CREATE TABLE IF NOT EXISTS user(
            id INT UNSIGNED NOT NULL AUTO_INCREMENT,
            username VARCHAR(20) NOT NULL UNIQUE,
            password CHAR(32) NOT NULL,
            email VARCHAR(30) NOT NULL,
            PRIMARY KEY (id)
        )ENGINE=InnoDB DEFAULT CHARSET UTF8;
EOF;
    $pdo->exec($sql); // 使用 PDO 对象的 exec()方法执行建表语句
    // 写入 SQL 语句
    $rand = mt_rand(0, 999);
    $sql = sprintf('INSERT INTO user (username, password, email) VALUES ("%s","%s","%s")', 'user' . $rand, md5($rand), 'email' . $rand . '@163.com');
    $pdo->exec($sql); // 执行成功,返回 int(1)
    $pdo->lastInsertId(); // 返回最后写入的主键值,即主键的自增值
    // 一次写入多条
    $arr = [
        ['username' => 'username' . mt_rand(0, 999), 'password' => md5(mt_rand(0, 999)), 'email' => 'email' . mt_rand(0, 999) . '@outlook.com'],
        ['username' => 'username' . mt_rand(0, 999), 'password' => md5(mt_rand(0, 999)), 'email' => 'email' . mt_rand(0, 999) . '@icloud.com'],
        ['username' => 'username' . mt_rand(0, 999), 'password' => md5(mt_rand(0, 999)), 'email' => 'email' . mt_rand(0, 999) . '@163.com'],
    ];
    $sql = 'INSERT INTO user (username, password, email) VALUES ';
    foreach ($arr as $v) {
        $sql .= "('{$v['username']}', '{$v['password']}', '{$v['email']}'),";
    }
    $sql = rtrim($sql, ',');
    $pdo->exec($sql); // 返回受影响行数 int(3)
} catch (PDOException $e) {
    echo $e->getMessage();
}

执行 pdo 对象的 exec() 方法返回受影响的行数、0[例如上例执行创建表的语句返回 0 ] 或者 false [当 SQL 语句错误,使用 errorInfo() 方法获取错误信息。]

exec() 更新与删除

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"));
    // 更新
    $sql = "UPDATE user SET username='user1' where id = 1;";
    $pdo->exec($sql); // 返回受影响行数
    // 删除
    $sql = 'DELETE FROM user where id = 1;';
    $pdo->exec($sql); // 返回受影响的行数
    // 执行 SELECT 操作
    $sql = 'SELECT * FROM user;';
    $pdo->exec($sql); // 返回 int(0)
} catch (PDOException $e) {
    echo $e->getMessage();
}

不允许使用 exec() 进行 SELECT 操作。

query() 查询

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"));
    $sql = 'SELECT * FROM user where id = 2';
    $res = $pdo->query($sql); // object(PDOStatement)#2 (1) { ["queryString"]=> string(31) "SELECT * FROM user where id = 2" }
    // 通过 foreach 遍历对象
    foreach ($res as $row) {
        print_r($row);
    }
} catch (PDOException $e) {
    echo $e->getMessage();
}

设置数据库连接属性

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $options = [PDO::ATTR_AUTOCOMMIT => 0];
    $pdo = new PDO($dsn, $username, $passwd, $options); // 实例化 PDO 对象时传入属性
    /**
     * PDO::ATTR_AUTOCOMMIT 自动提交
     * PDO::ATTR_CASE 字段名大小写
     * PDO::ATTR_CLIENT_VERSION 客户端版本
     * PDO::ATTR_CONNECTION_STATUS 连接状态信息
     * PDO::ATTR_DRIVER_NAME
     * PDO::ATTR_ERRMODE 错误处理模式
     * PDO::ATTR_ORACLE_NULLS 空字符串转换成SQL时的 Null
     * PDO::ATTR_PERSISTENT
     * PDO::ATTR_PREFETCH
     * PDO::ATTR_SERVER_INFO 服务器信息
     * PDO::ATTR_SERVER_VERSION 服务器版本
     * PDO::ATTR_TIMEOUT 超时时间
     */
    $pdo->getAttribute(PDO::ATTR_AUTOCOMMIT); // 获取连接属性值
    $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0); // 设置连接属性
} catch (PDOException $e) {
    echo $e->getMessage();
}

错误信息

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"));
    $sql = 'SELECT * FROM users'; // 表名不正确
    $res = $pdo->exec($sql);
    if ($res === false) {
        echo $pdo->errorCode(); // 返回SQLSTATE的值 42S02
        print_r($pdo->errorInfo()); // 返回错误信息的数组,[0=>'SQLSTATE值', 1=>'错误码', 2=>'错误提示'],Array ( [0] => 42S02 [1] => 1146 [2] => Table 'test.users' doesn't exist )
    }
} catch (PDOException $e) {
    echo $e->getMessage();
}

quote() 防止 SQL 注入

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $username = ' or 1 = 1 #';
    // $pdo->quote('username');
    $pdo->quote($username); // quote() 过滤 SQL 字符串中特殊字符
    $sql = "SELECT * FROM user where username = '{$username}'";
    $pdo->query($sql);
} catch (PDOException $e) {
    echo $e->getMessage();
}

使用 quote() 方法会转移特殊字符,防止SQL注入,但是不建议这样操作。

预处理查询

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"));
    $sql = "SELECT * FROM user";
    // 准备一条 SQL 语句
    $res = $pdo->prepare($sql); // object(PDOStatement)#2 (1) { ["queryString"]=> string(43) "SELECT * FROM user where username='user291'" }
    // execute() 执行 SQL 语句
    $r = $res->execute(); // 返回 boolean
    $res->setFetchMode(PDO::FETCH_ASSOC); // 设置返回数据的格式
    // $res->fetchAll();
    if ($r) {
        while ($row = $res->fetch(PDO::FETCH_ASSOC)) { // 获取结果集中一条数据 PDO::FETCH_ASSOC 参数返回关联数组
            var_dump($row);
        }
    }
} catch (PDOException $e) {
    echo $e->getMessage();
}

预处理语句中占位符的使用

  • 在调用

    execute()

    的时候传入对应的值,进行语句的预处理。

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $username = ' or 1 = 1 #'; // 'username430'
    $sql = "SELECT * FROM user where username = :username"; // 不用给字符串 :username 加上引号
    $res = $pdo->prepare($sql); // prepare() 过滤 SQL 字符串中特殊字符
    $res->execute([':username' => $username]);
} catch (PDOException $e) {
    echo $e->getMessage();
}
  • 使用

    ?

    占位符,预处理完 SQL 后使用

    excute()

    的时候,相当于传递一个索引数组。

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $username = 'username430';// ' or 1 = 1 #'; // 'username430'
    $sql = "SELECT * FROM user where username = ?"; // 不用给字符串 :username 加上引号
    $res = $pdo->prepare($sql); // prepare() 过滤 SQL 字符串中特殊字符
    $res->execute([$username]);
    var_dump($res->rowCount());
} catch (PDOException $e) {
    echo $e->getMessage();
}
  • bindParam()

    方法绑定参数

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $sql = 'INSERT INTO user (username, password, email) VALUES (:username, :password, :email)';
    $statement = $pdo->prepare($sql); // 预执行SQL
    $statement->bindParam(':username', $username, PDO::PARAM_STR); // 绑定参数 :username
    $statement->bindParam(':password', $password, PDO::PARAM_STR);
    $statement->bindParam(':email', $email, PDO::PARAM_STR);
    // 参数赋值
    $rand = mt_rand(0, 999);
    $username = 'username' . $rand;
    $password = md5($rand);
    $email = $username . '@qq.com';
    $statement->execute();
} catch (PDOException $e) {
    echo $e->getMessage();
}

bindValue() 将值绑定到参数

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $sql = 'INSERT INTO user (username, password, email) VALUES (:username, :password, :email)';
    $statement = $pdo->prepare($sql);
    $rand = mt_rand(0, 999);
    $username = 'username' . $rand;
    $password = md5($rand);
    $statement->bindValue(':username', $username);
    $statement->bindValue(':password',$password);
    $statement->bindValue(':email',$rand . '@126.com');
    $statement->execute();
    echo $statement->rowCount();
    // 再次绑定值,但是 email 字段使用上面的值
    $rand = mt_rand(0, 999);
    $username = 'username' . $rand;
    $password = md5($rand);
    $statement->bindValue(':username', $username);
    $statement->bindValue(':password',$password);
    $statement->execute();
    echo $statement->rowCount();
} catch (PDOException $e) {
    echo $e->getMessage();
}

注意: 赋值的 $username$password 的赋值要在 bindValue() 之前。

bindColum() 绑定参数到列

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $sql = 'SELECT username,password,email FROM user';
    $statement = $pdo->prepare($sql);
    $statement->execute();
    $statement->columnCount(); // 获取结果集中列数
    $statement->bindColumn(1, $username);
    $statement->bindColumn(2, $password);
    $statement->bindColumn(3, $email);
    while ($statement->fetch(PDO::FETCH_BOUND)) {
        echo 'username:',$username,',password:',$password,',email:',$email;
    }

} catch (PDOException $e) {
    echo $e->getMessage();
}

fetchColumn() 从结果集下一行返回单独的行

<?php

try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $sql = 'SELECT username,password,email FROM user';
    $statement = $pdo->prepare($sql);
    $statement->execute();
    echo $statement->fetchColumn();
    echo $statement->fetchColumn(2); // 获取第 2 行的 password 字段值
} catch (PDOException $e) {
    echo $e->getMessage();
}

debugDumpParams() 打印预处理语句

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=test';
    $username = 'root'; // 数据库用户名
    $passwd = 'aaaaaa'; // 数据库密码
    $pdo = new PDO($dsn, $username, $passwd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8")); // 实例化 PDO 对象时传入属性
    $sql = 'SELECT username,password,email FROM user WHERE id > :id';
    $statement = $pdo->prepare($sql);
    $statement->bindParam(':id', $id, PDO::PARAM_INT);
    $id = 10;
    $statement->execute();
    print_r($statement->debugDumpParams());
} catch (PDOException $e) {
    echo $e->getMessage();
}


Article précédent: Article suivant: