<?php练功房

第 5 章 · Web 开发 · 第 5.3 课

用 PDO 操作数据库

约 20 分钟

网站的数据(用户、文章、订单)都存在数据库里。PHP 用 PDO 统一操作各种数据库:MySQL、PostgreSQL、SQLite……换数据库时只要改连接字符串。

练功房里用的是 SQLite 内存数据库(sqlite::memory:),不用安装,每次运行都是一个全新的空数据库。连接 MySQL 时只是第一行不同:

<?php
$pdo = new PDO('mysql:host=127.0.0.1;dbname=shop;charset=utf8mb4', '用户名', '密码');

建表、插入、查询

  • exec($sql):执行不返回结果的语句(建表等)。
  • prepare($sql) + execute([...]):预处理语句,SQL 里的值用 ? 占位,数据单独传进去。
  • fetchAll(PDO::FETCH_ASSOC):取出所有行,每行是一个关联数组。
  • lastInsertId():刚插入那一行的自增 id。

带条件的查询、修改和删除

占位符也可以起名字::max,传参时用关联数组。rowCount() 返回受影响的行数。

SQL 注入:为什么一定要用预处理语句

如果把用户输入直接拼进 SQL 字符串,攻击者就能输入一段精心构造的文字,改变 SQL 语句本身的含义。下面这个登录检查,攻击者不知道密码也能登进去。

选择题

防止 SQL 注入最可靠的做法是?

练习 1

查询及格的学生

表 students 已经建好了。查询分数大于等于 $pass 的学生,按分数从高到低排序,每行输出一个名字。分数线要通过占位符传进 SQL。期望输出:

小红
小刚
小明

练习 2

添加用户

写函数 addUser(PDO $pdo, string $name, int $age): int:用预处理语句往 users 表插入一行,返回新行的 id。

检查时会插入一个叫 O'Brien 的用户,名字里有单引号。如果你拼接字符串,SQL 就会出错。