跳转至

PHP PDO

约 924 个字 154 行代码 预计阅读时间 5 分钟

开启

Linux下

width-pdo-mysql=/usr/local/mysql

后面是mysql的目录。

Windows下

php.ini 中开启:

1
2
3
4
5
6
7
8
# PDO驱动程序共享扩展必须有
extension=php_pdo.dll
# MySQL扩展
extension=php_pdo_mysql.dll
# SQL Server扩展
extension=php_pdo_mssql.dll
# Oracle扩展
extension=php_pdo_oci.dll

初始化

语句

$pdo = new PDO($dsn[, $user, $password, $driver_options]);
  • $dsn:字符串,表示连接参数。
  • $driver_options:数组,驱动器配置。不过建议通过在后期设置 PDO 属性来设置。

$dsn 写法

有 3 种写法。

写法 1:常规写法

"mysql:host=$server;dbname=$db"

其中 $server 为服务器地址,$db 是数据库名。如:

1
2
3
4
5
try {
    $pdo = new   PDO("mysql:host=localhost;dbname=hyerp", 'root', '');
} catch(PDOException $e) {
    die("数据库连接失败" . $e -> getMessage());
}

写法 2:文件

$dsn 的字符串写入一个文件(以下记为 $path )中,然后在初始化时的 $dsn 位置处填上 "uri:$path"。如:

# pdo.ini
mysql:host=localhost;dbname=hyerp
1
2
3
4
5
try {
    $pdo = new PDO("uri:pdo.ini", 'root', '');
} catch(PDOException $e) {
    die("数据库连接失败" . $e -> getMessage());
}

写法 3:写在 php.ini

在初始化时的 $dsn 位置处填上 "mysqlpdo"。如:

1
2
3
# php.ini
[PDO]
pdo.dsn.mysqlpdo = "mysql:host=localhost;dbname=hyerp"

完成后需要重启 HTTP 服务器。在 PHP 文件中这样写:

1
2
3
4
5
try {
    $pdo = new PDO("mysqlpdo", 'root', '');
} catch(PDOException $e) {
    die("数据库连接失败" . $e -> getMessage());
}

属性与方法

PDO 属性

1
2
3
4
5
// 获取 PDO 属性
$pdo -> getAttribute($type)

// 设置 PDO 属性
$pdo -> setAttribute($type, $val)

其中 $type 为整数。PDO有以下常量供使用:

  • PDO::ATTR_AUTOCOMMIT:是否开启了自动提交
  • PDO::ATTR_CASE:是否是大写
  • PDO::ATTR_CLIENT_VERSION:客户端版本
  • PDO::ATTR_DRIVER_NAME:驱动器名称
  • PDO::ATTR_SERVER_INFO:服务器信息
  • PDO::ATTR_SERVER_VERSION:服务器版本
  • PDO::ATTR_ERRMODE:异常处理方式,为整数
  • ……

查询

$pdo -> query($sql)

返回 PDOStatement(预处理)对象(下文为 $stmt)。

增删改

$pdo -> exec($sql)

返回影响行数。

解析数据

$stmt -> fetchAll([$opt])

返回数组。

如果不设置 $opt,返回的数组包括数字的索引和键值对的部分:

Array
(
[0] => Array
    (
        [name] => 'haha'
        [0] => 'haha'
        [desp] => 'gege'
        [1] => 'gege'
    )
[1] => Array
    (
        [name] => 'papa'
        [0] => 'papa'
        [desp] => 'tete'
        [1] => 'tete'
    )
)

如果只想返回键值对的结果,设置 $optPDO::FETCH_ASSOC

释放资源

$stmt = null;
$pdo = null;

需要将预处理对象和PDO对象设为 null

数据遍历的步骤

  1. 连接数据库
    1
    2
    3
    4
    5
    try {
      $pdo = new   PDO("mysql:host=localhost;dbname=hyerp", 'root', '');
    } catch(PDOException $e) {
      die("数据库连接失败" . $e -> getMessage());
    }
    
  2. 执行查询,返回预处理对象
    1
    2
    3
    $sql = "select * from stu";
    $stmt = $pdo -> query($sql);
    $list = $stmt -> fetchAll(PDO::FETCH_ASSOC);
    
  3. 解析数据
    1
    2
    3
    foreach($list as $val) {
      echo $val['id'] . "-----" . $val['name'] . "<br>";
    }
    
  4. 释放资源
    $stmt = null;
    $pdo = null;
    

第 2、3 步的快捷方法

1
2
3
4
$sql = "select * from stu";
foreach($pdo -> query($sql) as $val) {
  echo $val['id'] . "-----" . $val['name'] . "<br>";
}

但是不代表 $stmt = $pdo -> query($sql); 之后,$stmt 可迭代。

错误处理

获取错误

PDO 默认不提示错误信息,需要用下面的命令得到:

$pdo -> errorCode()

得到的值为 SQLSTATE 错误代码,为字符串。当大于 0 时,表示出错。

若执行:

$pdo -> errorInfo()

返回错误信息,为数组:

1
2
3
4
5
Array (
    [0] => SQLSTATE 错误代码
    [1] => 驱动错误码
    [2] => 驱动错误信息
)

让PDO在错误的时候报错

下面每一组的上下两行代码功能相同,只需要写一个即可。

1
2
3
4
5
6
7
8
9
// 默认:不提示
$pdo -> setAttrbute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$pdo -> setAttrbute(PDO::ATTR_ERRMODE, 0);
// 警告模式
$pdo -> setAttrbute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$pdo -> setAttrbute(PDO::ATTR_ERRMODE, 1);
// 异常模式
$pdo -> setAttrbute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo -> setAttrbute(PDO::ATTR_ERRMODE, 2);

PDO 预处理

预处理 SQL 语句

$pdo -> prepare($sql)

返回 PDOStatement 对象。$sql 中的未确定量用 ?:var 代替。

为预处理对象绑定值

$stmt -> bindValue($index, $val)

$index1 开始,或为对应的 "var"

为预处理对象绑定变量

$stmt -> bindParam($index, $var)

为上面的预处理对象绑定一个变量 $var$index1 开始,或为对应的 "var"。在此之后或之前对 $var 赋值。

执行

$stmt -> execute()

执行上面的预处理对象。

返回影响行数

$stmt -> rowCount()

整数。

为查询结果的指定列绑定变量

$stmt -> bindColumn($index, $var)

为预处理对象返回的查询结果的指定列绑定一个变量 $var$index1开始,或为对应的 "var"。在此之后或之前对 $var 赋值。

预处理查询方法方式

问号式预处理方式

将SQL语句中未定义项以问号代替,再在后面绑定参数。参数绑定方式有三种:

直接绑定值

//预处理SQL语句
$sql = "insert into stu(id, name, sex, age) values (?, ?, ?, ?)";
$stmt = $pdo -> prepare($sql);
//对问号处参数绑定
$stmt -> bindValue(1, null);
$stmt -> bindValue(2, 'test');
$stmt -> bindValue(3, 'w');
$stmt -> bindValue(4, 22);
//执行
$stmt -> execute();
echo $stmt -> rowCount();

先绑定变量,再为变量赋值;或者是先为变量赋值,再绑定变量

//预处理SQL语句
$sql = "insert into stu(id, name, sex, age) values (?, ?, ?, ?)";
$stmt = $pdo -> prepare($sql);
//对问号处参数绑定
$stmt -> bindParam(1, $id);
$stmt -> bindParam(2, $name);
$stmt -> bindParam(3, $sex);
$stmt -> bindParam(4, $age);
$id = null;
$name = 'test';
$sex = 'w';
$age = 22;
//执行
$stmt -> execute();
echo $stmt -> rowCount();

在执行时通过数组赋值

1
2
3
4
5
6
//预处理SQL语句
$sql = "insert into stu(id, name, sex, age) values (?, ?, ?, ?)";
$stmt = $pdo -> prepare($sql);
//执行
$stmt -> execute(array(null, 'test', 'w', 22));
echo $stmt -> rowCount();

别名式预处理方式

将问号以 :var 形式的别名(和列名无关)代替。

参数绑定时,$index 为对应的 "var"

上面的三种绑定方式同样适用于此(以直接绑定值为例):

//预处理SQL语句
$sql = "insert into stu(id, name, sex, age) values (:id, :nm, :sex, :age)";
$stmt = $pdo -> prepare($sql);
//对问号处参数绑定
$stmt -> bindValue("id", null);
$stmt -> bindValue("nm", 'test');
$stmt -> bindValue("sex", 'w');
$stmt -> bindValue("age", 22);
//执行
$stmt -> execute();
echo $stmt -> rowCount();

在执行时通过数组赋值时,要写上下标:

$stmt -> execute(array("id" => null, "nm" => 'test', "sex" => 'w', "age" => 22));

绑定结果的预处理方式

$stmt -> execute(); 后,使用 $stmt -> bindColumn($index, $var) 对列进行绑定:

$stmt -> execute();

$stmt -> bindColumn(1, $id);
$stmt -> bindColumn(2, $name);
$stmt -> bindColumn("sex", $sex);
$stmt -> bindColumn("age", $age);

while($row = $stmt -> fetch(PDO::FETCH_COLUMN)) {
  echo "{$id}:{$name}:{$sex}:{$age}<br>";
}

PDO 事务处理

数据表类型

数据表要用 InnoDB 类型。

开启一个事务

(做一个回滚点)

$pdo -> beginTransaction()

提交事务

$pdo -> commit()

事务回滚操作

$pdo -> rollBack()

来源

【极客学院】PHP 全套教学视频_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili