# 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()` 方法可以用来执行数据库的 `INSERT` 、`UPDATE`、`DELETE`操作。并且不支持 `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();
}
```
- 写在前面
- MySQL的使用
- MySQL多表同时删除方案
- MySQL跨表、多表更新SQL语句总结
- MySQL存储引擎
- 安装
- 常规方式编译安装MySQL
- 采用cmake方式编译安装MySQL
- 使用rpm包安装MySQL
- 使用yum方式安装MySQL
- 采用二进制方式免编译安装MySQL
- 多实例的安装
- 什么是多实例
- 多实例的作用、问题以及应用场景
- 多实例安装01【推荐】
- 多实例官方安装方案02
- 启动、用户和权限管理
- 单实例MySQL的启动和关闭的方法
- 设置及修改MySQL root用户密码
- 找回丢失的MySQL root用户密码
- 创建MySQL用户及用户权限管理
- 基础命令的操作
- MySQL库和表相关操作
- MySQL中的索引操作
- MySQL常用命令
- MySQL的错误代码
- MySQL复习秘籍
- 备份与恢复
- 备份
- 恢复
- mysqlbinlog命令
- 服务日志
- 主从复制
- 主从复制部署配置问题汇总
- 主从复制读写分离
- 灾难恢复
- 配置phpmyadmin连接多实例MySQL
- 其他相关
- Sphinx实验
- 中文分词技术
- MySQL语句大全
- 用户创建、权限、删除
- 数据库与表显示、创建、删除
- 表复制及备份还原
- 数据库表中数据操作
- 修改表的列与表名
- 修改表中的数据
- 查询表
- 日志
- 批量修改Mysql表引擎为InnoDB的方法
- 数据库抽象层 PDO
- PDO对象常用方法
- PDO 事务处理
- PDO 与 MySQLi 二者效率简单比较
- 大小写敏感性 lower_case_table_names
- CentOS7安装MySQL5.7密码查看与修改