MENU

PHP 中 使用 PDO 扩展操作 MySQL 数据库

February 4, 2020 • 开发

基础操作

1. 连接数据库

$user = 'root';
$pass = 'root';
$host = '127.0.0.1';
$port = 3306;
$dbname = 'testdb';

$dsn = "mysql:host=$host;port=$port;dbname=$dbname";

try {
    $dbh = new PDO($dsn, $user, $pass);
    echo '连接成功';
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}

默认采用短链接的方式连接数据库,若需开启长链接需添加以下参数:

$dbh = new PDO($dsn, $user, $pass, [PDO::ATTR_PERSISTENT => true]);

2. 创建数据表

$sql = "create table student(
        id int unsigned primary key auto_increment,
        name char(10) not null
    );";

$dbh->exec($sql); // 返回 0

使用 exec 方法执行 SQL 语句,没有结果返回。

3. 查询、处理记录

$sql = "select * from student limit 10;";
$stmt = $dbh->query($sql);

$result = $stmt->fetchAll(); // 默认返回格式为:关联数组和对象
$result = $stmt->fetchAll(PDO::FETCH_ASSOC); // 只返回关联数组格式
$result = $stmt->fetchAll(PDO::FETCH_OBJ);   // 只返回对象格式

查询数据使用 query 方法,将返回 PDOStatement 类的实例。

4. 添加、修改、删除记录

添加记录:

$sql = "insert into student(name) value ('小红');";
$result = $dbh->exec($sql); // 返回 1,影响了 1 条数据

编辑记录:

$sql = "update student set name='小白' where name='小黄'";
$result = $dbh->exec($sql); // 返回 1,影响了 1 条数据

删除记录:

$sql = "delete from student where name='小白';";
$result = $dbh->exec($sql); // 返回 1,影响了 1 条数据

预处理语句

虽然上述的写法已经实现了正删改查,但是通过拼接的 SQL 语句极容易发生 SQL 注入攻击,这时候预处理语句就很好的避免了这类安全问题。简单的说预处理语句就像一个 SQL 语句的模版,可以使用相同或不同的参数多次执行,传入的参数会被数据库自动处理,可以确保不会发生SQL 注入,同时占用资源更少、更高效。

1. 通过命名占位符绑定

// 预处理及绑定
$stmt = $dbh->prepare('insert into student(name) value (:name)');
$stmt->bindParam(':name', $name);

// 执行语句
$name = '张三';
$stmt->execute();

2. 通过 ?占位符绑定

// 预处理及绑定
$stmt = $dbh->prepare('insert into student(name) value (?)');
$stmt->bindParam(1, $name);

// 执行语句
$name = '李四';
$stmt->execute();

个人觉得通过命名占位符绑定的方式要更清晰,推荐使用命名占位符。

事务操作

当程序中某一个操作需要执行多条 SQL 语句时,就需要使用事务来保证这多条 SQL 全部正常执行了。

1. 提交事务

$dbh->beginTransaction(); // 开启事务

$stmt = $dbh->prepare('delete from student where name=:name');
$stmt->bindParam(':name', $name);

$name = '小白';
$stmt->execute();

$name = '小红';
$stmt->execute();

$dbh->commit(); // 提交事务

2. 回滚事务

$dbh->beginTransaction(); // 开启事务

$stmt = $dbh->prepare('delete from student where name=:name');
$stmt->bindParam(':name', $name);

$name = '小白';
$stmt->execute();

$name = '小红';
$stmt->execute();

$dbh->rollback(); // 回滚事务