## 预处理语句
什么是预处理语句?可以把它看作是想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制。
预处理语句可的两大好处:
* 查询仅需解析一次,但可以用相同或不同的参数执行多次。当查询准备好后,数据库将分析、编译和优化执行该查询的计划。对于复杂的查询,此过程要花费较长的时间,如果需要以不同参数多次重复相同的查询,那么该过程将大大降低应用程序的速度。通过使用预处理语句,可以避免重复分析/编译/优化周期。
* 提供给预处理语句的参数不需要用引号括起来,驱动程序会自动处理。如果应用程序只使用预处理语句,可以确保不会发生SQL 注入。(然而,如果查询的其他部分是由未转义的输入来构建的,则仍存在 SQL 注入的风险)。
PDOStatement 对象常用的方法:
* PDOStatement::bindColumn — 绑定一列到一个 PHP 变量
* PDOStatement::bindParam — 绑定一个参数到指定的变量名(**引用传递**)
* PDOStatement::bindValue — 把一个值绑定到一个参数(**只读传递**)
* PDOStatement::closeCursor — 关闭游标,使语句能再次被执行。
* PDOStatement::columnCount — 返回结果集中的列数
* PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令
* PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE
* PDOStatement::errorInfo — 获取跟上一次语句句柄操作相关的扩展错误信息
* PDOStatement::execute — 执行一条预处理语句
* PDOStatement::fetch — 从结果集中获取下一行
* PDOStatement::fetchAll — 返回一个包含结果集中所有行的数组
* PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列。
* PDOStatement::fetchObject — 获取下一行并作为一个对象返回。
* PDOStatement::getAttribute — 检索一个语句属性
* PDOStatement::getColumnMeta — 返回结果集中一列的元数据
* PDOStatement::nextRowset — 在一个多行集语句句柄中推进到下一个行集
* PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数
* PDOStatement::setAttribute — 设置一个语句属性
* PDOStatement::setFetchMode — 为语句设置默认的获取模式。
参考链接: [PDOStatement 对象](http://php.net/manual/zh/class.pdostatement.php)
```
<?php
$pdo = new PDO('mysql:host=localhost;dbname=koogua_forum', 'root', '123456');
/* ------------- 插入操作 ------------- */
// 使用命名占位符
$name = 'foo';
$about = 'I am foo';
$stmt = $pdo->prepare("INSERT INTO Tag (name, about) VALUES (:name, :about)");
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->bindParam(':about', $about, PDO::PARAM_STR);
$stmt->execute();
// 使用问号占位符
$name = 'bar';
$about = 'I am bar';
$stmt = $pdo->prepare("INSERT INTO Tag (name, about) VALUES (?, ?)");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->bindValue(2, $about, PDO::PARAM_STR);
$stmt->execute();
/* ------------- 更新操作 ------------- */
$name = 'php5';
$about = 'I am php5';
$id = 1;
$stmt = $pdo->prepare("UPDATE Tag SET name = :name, about = :about WHERE id = :id");
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
$stmt->bindValue(':about', $about, PDO::PARAM_STR);
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
$stmt->execute();
/* ------------- 删除操作 ------------- */
$id = 8;
$sql = "DELETE FROM Tag WHERE id = :id";
$stms = $pdo->prepare($sql);
$stms->bindValue(':id', $id, PDO::PARAM_INT);
$stms->execute();
/* ------------- 查询操作 ------------- */
$sql = "SELECT * FROM Tag WHERE id > :id";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':id', 3, PDO::PARAM_INT);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
echo "name:{$row->name}, about:{$row->about}" .PHP_EOL;
}
$stmt->closeCursor();
echo "--- rows begin with php ---" . PHP_EOL;
$sql = "SELECT * FROM Tag WHERE name LIKE :name";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':name', 'php%', PDO::PARAM_STR);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
echo "name:{$row->name}, about:{$row->about}" .PHP_EOL;
}
?>
```
- 基本语法
- PHP标记
- 指令分隔符
- 从HTML中分离
- 注释
- 数据类型
- 布尔值
- 整数
- 浮点数
- 字符串
- 数组
- 对象
- 资源
- 空值
- 变量
- 基础
- 预定义变量
- 变量范围
- 可变变量
- 常量
- 常量语法
- 魔术常量
- 运算符
- 算术运算符
- 赋值运算符
- 位运算符
- 比较运算符
- 递增与递减运算符
- 逻辑运算符
- 字符串运算符
- 数组运算符
- 类型运算符
- 流程控制
- if条件结构
- switch条件结构
- while循环结构
- do-while循环结构
- for循环结构
- foreach循环结构
- 包含文件
- 函数
- 自定义函数
- 可变函数
- 匿名函数
- 递归函数
- 类与对象
- 基本概念
- 属性
- 方法
- 类常量
- 构造函数和析构函数
- 访问控制
- 继承
- 抽象类
- 接口
- Trait
- 重载
- 对象遍历
- 魔术方法
- Final关键字
- 命名空间
- 自动加载
- 错误处理
- 错误显示
- 错误日志
- 错误报告
- 自定义错误处理
- 异常处理
- 异常处理机制
- 扩展异常处理类
- 字符操作
- 数组操作
- 时间操作
- 表单操作
- GET提交
- POST提交
- 文件上传
- 会话控制
- COOKIE操作
- SESSION操作
- 文件操作
- 文件属性
- 读取文件
- 写入文件
- 文件管理
- 文件锁
- 目录处理
- 路径处理
- 网络操作
- HTTP协议
- Socket操作
- CURL操作
- PDO操作
- 介绍
- 连接管理
- 预处理语句
- 事务处理
- 错误处理
- 图像操作
- 正则表达式
- 标准推荐
- 包管理器
- 设计模式
- 常用算法
- 安全防御
- XSS防御
- CSRF防御