1.1 PDO是什么
* PDO: PHP 数据对象
* PDO提供了一个数据访问抽象层
1.2 为什么用PDO操作数据库
* 任何类型的数据库,都可以通过PDO进行统一管理
* 用户不再需要为不同的数据库编写不同的代码
2.使用PDO连接数据库
<?php // POD 操作 // 数据库连接与创建PDO对象 // 连接参数 // 数据源 $dsn = 'mysql:host=localhost;dbname=php'; // 数据库主机默认就是localhost/127.0.0.1,所以可省略 $dsn = 'mysql:dbname=php'; // 用户名 $user = 'root'; // 密码 $password = 'root'; // 实例化PDO类,连接成功并返回PDO对象 // try-catch 结构可以捕获到执行期的任何错误 try { $pdo = new PDO($dsn, $user, $password); } catch (PDOException $e) { exit('Connection failed:' . $e->getMessage()); } // 测试 $sql = "SELECT `name`,`position` FROM `staff`"; var_dump($pdo); // 返回pdo对象 echo '<hr>'; // 查询测试 foreach ($pdo->query($sql) as $row) { echo $row['name'].'=>'.$row['position'].'<br>'; } // 断开 $pdo = null; // NULL var_dump($pdo);
3. 预处理对象
* 预处理过程: 对SQL语句的模板进行编译检查,并缓存,以提升执行效率
* 执行预处理的工具是: 预处理对象 `PDOStatement`
* SQL语句模板中的用户数据,使用命名占位符: `:命名标识符`
* 调用pdo对象的prepare()方法
* `PDOStatement`预处理对象
* 预处理对象,以后我们用stmt来简写
* stmt对象提供了非常多的方法,可以非常优雅高效的实现`CURD`操作
<?php // 预处理对象 $sql = "SELECT * FROM `staff` WHERE `age` >40 AND `sex`=1"; // 制作SQL语句模板 //分析: 语句中的用户数据是查询条件的值,年龄,使用占位符表示, $sql = "SELECT * FROM `staff` WHERE `age` > :age AND `sex`= :sex"; // 创建预处理对象 // 1. 创建pdo对象,连接数据库 $pdo = new PDO('mysql:dbname=php','root', 'root'); // 2. 调用 prepare()创建预处理对象 $stmt = $pdo->prepare($sql); // 查看预处理对象 var_dump($stmt); echo '<hr>'; // 查看生成的sql语句模板字符串 echo $stmt->queryString;
4.SQL语句对象的参数绑定(如何将参数传入参数占位符中)
* `bindValue()`: 将一个变量的值,绑定到SQL语句对象的参数上
* `bindParam()`: 将一个变量的引用,绑定到SQL语句对象的参数上
* 二者功能类似,区别如下:
* `bindValue()`: 类似于将常量绑定到SQL语句参数上,可以使用字面量
* `bindParam()`: 可以实时动态的改变SQL语句模板中的命名参数
<?php // pdo 查询操作 // 重点掌握参数绑定的原理与使用场景 // 1. 连接数据库 $pdo = new PDO('mysql:dbname=php','root','root'); // 2. 准备要执行的语句,并返回语句对象 // 2.1 SQL语句模板 $sql = "SELECT `id`,`name`,`position` FROM `staff` WHERE `id`= :id "; // 2.2 创建预处理对象 $stmt = $pdo->prepare($sql); // 3. 执行一条预处理语句 // 3.1 参数绑定 // 绑定参数有二个方法可用 // bindValue(): 将一个变量的值,绑定到SQL语句对象的参数上 //支持变量,字面量,是典型的值传递,不能改变SQL语句中的参数,适合单条查询 // bindParam(): 将一个变量的引用,绑定到SQL语句对象的参数上 //仅允许变量,以引用方式绑定到SQL语句对象中 // 因为bindParam()可以也可以实现bindValue()功能,并且适合范围更广,以后我们就只用bindParam() $id = 1; // PDO::PARAM_INT 是预定义PDO常量,设置参数数据类型,否则默认为字符串类型 $stmt->bindValue('id',$id,PDO::PARAM_INT); // bindParam()才可以查询到下一条记录 $stmt->bindParam('id',$id,PDO::PARAM_INT); $stmt->execute(); // fetch(): 从结果集中获取下一条记录 // fetch(): 主要用于获取单条记录,并自动下移记录指针到下一条记录 $result = $stmt->fetch(PDO::FETCH_ASSOC); print_r($result); echo '<hr>'; // 获取id = 2的记录 $id = 2; // bindValue()不支持$id动态设置, 必须用bindParam(),因为它是引用传参,会更新SQL语句模板 $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); print_r($result);
5.除了使用以上两种方式绑定sql模板的参数,还可以使用execute()直接传参绑定
<?php // 1. 连接数据库,创建PDO对象 $pdo = new PDO('mysql:dbname=php','root','root'); // 2. 准备SQL语句,创建预处理对象 $sql = "SELECT `id`,`name`,`position` FROM `staff` WHERE `id` BETWEEN :start AND :stop"; $stmt = $pdo->prepare($sql); // 3. 执行SQL语句 $stmt->execute(['start'=>2, 'stop'=>5]); // 4. 遍历结果集,返回二维数组 $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); //var_dump($rows); foreach ($rows as $row) { echo '<pre>', print_r($row,true); } // 5. 关闭连接,如果不断开,系统也会自动切断 $pdo = null;
查询操作(1):fetch()
* `fetch()`: 获取一条记录后,会自动下移记录指针,所以非常适合用循环来遍历结果集
* `fetch()`: 以一维数组的方式返回查询结果,默认会包括索引与关联二部分
* 通常用户只关心关联部分,可以设置查询模式参数解决: `setFetchMode()`
* `$stmt->setFetchMode(PDO::FETCH_ASSOC);`
查询操作(2): fetchAll()
* `fetchAll()`: 可一次性获取到所有满足条件的记录,返回二维数组
* 如果数据表中记录过多,有可能对内存造成一定的压力
<?php // 1. 连接数据库,创建PDO对象 $pdo = new PDO('mysql:dbname=php','root','root'); // 2. 准备SQL语句,创建预处理对象 $sql = "SELECT `id`,`name`,`position` FROM `staff` WHERE `id` BETWEEN :start AND :stop"; $stmt = $pdo->prepare($sql); // 3. 执行SQL语句 $stmt->execute(['start'=>2, 'stop'=>5]); // 4. 遍历结果集,返回二维数组 $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); //var_dump($rows); foreach ($rows as $row) { echo '<pre>', print_r($row,true); } // 5. 关闭连接,如果不断开,系统也会自动切断 $pdo = null;
查询操作(3): bindColumn()
* `bindColumn()`: 将查询结果集的字段绑定到指定变量
* `fetch(PDO::FETCH_BOUND)`: 必须使用`fetch`遍历,推荐设置获取常量
<?php // 1. 连接数据库,创建PDO对象 $pdo = new PDO('mysql:dbname=php','root','root'); // 2. 准备SQL语句,创建预处理对象 $sql = "SELECT `id`,`name`,`position` FROM `staff` WHERE `id` BETWEEN :start AND :stop"; $stmt = $pdo->prepare($sql); // 3. 执行SQL语句 $stmt->execute(['start'=>2, 'stop'=>5]); // 4. bindColumn()将结果集中的列绑定到指定变量上 // 注意与bindParam()的区别 $stmt->bindColumn('id', $id, PDO::PARAM_INT); $stmt->bindColumn('name', $name, PDO::PARAM_STR, 15); $stmt->bindColumn('position', $position, PDO::PARAM_STR, 20); // PDO::FETCH_BOUND: 指定获取方式,将结果集的列绑定到指定变量(可选) while ($stmt->fetch(PDO::FETCH_BOUND)) { echo 'id=' . $id . ', name=' . $name . ', position='. $position . '<hr>'; } // 5. 关闭连接,如果不断开,系统也会自动切断 $pdo = null;