# 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密碼查看與修改