page contents

PHP 数据库操作

PHP操作数据库的2种形式:使用 PDO 扩展类库(推荐)、使用 Mysqli 扩展类库(这是Mysql类库的升级版,但已经不推荐使用)。

attachments-2020-10-1wXXcpbi5f9b6cd61badd.jpg


PHP操作数据库的2种形式

  1. 使用 PDO 扩展类库(推荐)

  2. 使用 Mysqli 扩展类库(这是Mysql类库的升级版,但已经不推荐使用)


PDO 扩展包含哪三个类

  1. PDO

  2. PDOStatement

  3. PDOException


PDO 与 Mysqli 区别

  • PDO 可以支持多种数据库,而且操作方法一致

  • Mysqli 只支持Mysql数据库


如何使用PDO连接数据库?什么是DSN?如何关闭连接?

  • 通过new PDO()来连接数据库,其中必须传入DSN数据源名称

try {
$db = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
  • DSN(数据源名称)是告诉PDO使用哪款驱动来连接数据库,每一种数据库DSN都不同

Mysql的DSN mysql:host=localhost;dbname=test
oracle的DSN oci:dbname=//localhost:232/mydb;charset=utf-8

  • 关闭连接: $db = null;


PDO 与连接相关的选项如何设置?

  • 设置连接选项的2种方式

1、new PDO()的第四参数

//设置持久数据库连接必须使用这种方式,否则无效
$opt = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_TIMEOUT => 3600,
PDO::ATTR_AUTOCOMMIT => true
);
try {
$db = new PDO($dsn,$user,$password,$opt);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}

2、使用PDO对象的setAttribute()方法

try {
$db = new PDO($dsn,$user,$password);
$db -> setAttribute(PDO::ATTR_TIMEOUT, 3600);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
//与getAttribute()方法配套


PDO 错误处理模式该如何设置?

  • 错误处理模式有哪三种?

1、PDO::ERRMODE_SILENT (默认,不提示,需要结合errorCode()与errorInfo())
2、PDO::ERRMODE_WARNING (警告)
3、PDO::ERRMODE_EXCEPTION (报异常,推荐使用)

  • 一般使用案例

try {
$db = new PDO($dsn,$user,$password);
$db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}


PDO 执行SQL有哪些方法?

  • exec() ----不推荐,后面会有解释

exec() 主要:执行无结果集的SQL语句 增删改创建 返回影响行数

  • query() ----不推荐,后面会有解释

query() 主要:执行有结果集的SQL语句 查询 返回PDOStatement对象

对于某些SQL 既不是操作,也没有返回结果,使用上面某种方法都可以
  • prepare() ----推荐,后面会有解释


PDO 事务如何实现?

  1. 操作的Mysql的数据表必须是InnoDB

  2. 关闭自动提交 $db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);

  3. 开启事务 $db->beginTransaction();

  4. 手动提交 $db->commit();

  5. 事务回滚 $db->rollBack();

事务完成后,最好把自动提交开启 $db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);


什么是SQL注入?SQL注入如何防止?

  • SQL注入其实就是用户输入的数据带有攻击成分,所以用户输入的信息都是不可靠的

由于以上原因,导致之前exec()query()方法不常用,因为不安全,但只要不是用过用户数据生成的SQL都可以使用exec()query()

  • 使用预处理语句来防止SQL注入

try{
//只是将这个语句放到数据库上,编译后等待,没有执行
$stmt = $db -> prepare('insert into user(name,pwd,age) values(?,?,?)');

//绑定参数(?)
$stmt -> bindParam(1,$name);
$stmt -> bindParam(2,$pwd);
$stmt -> bindParam(3,$age);

$name = 'wwww';
$pwd = '12112';
$age = 18;

//执行存储在数据库中的语句
$stmt -> execute();

$name = 'bbb';
$pwd = 'ad22121';
$age = 20;

//执行存储在数据库中的语句
$stmt -> execute();
}catch(PDOException $e){
echo $e->getMessage();
exit();
}

简化模式:

try{
//只是将这个语句放到数据库上,编译后等待,没有执行
$stmt = $db -> prepare('insert into user(name,pwd,age) values(?,?,?)');

//执行存储在数据库中的语句
$stmt -> execute(array('wwww','12112',18));

}catch(PDOException $e){
echo $e->getMessage();
exit();
}


预处理语句中有哪两种占位符?注意事项是什么?

  • 2种占位符:命名占位符问号占位符

问号占位符就是上面那种
命名占位符,如下,推荐使用命名控制符

try{
//只是将这个语句放到数据库上,编译后等待,没有执行
$stmt = $db -> prepare('insert into user(name,pwd,age) values(:name,:pwd,:age)');

//绑定参数(?)
$stmt -> bindParam(1,$name);
$stmt -> bindParam(2,$pwd);
$stmt -> bindParam(3,$age);

$name = 'wwww';
$pwd = '12112';
$age = 18;

//执行存储在数据库中的语句
$stmt -> execute();

$name = 'bbb';
$pwd = 'ad22121';
$age = 20;

//执行存储在数据库中的语句
$stmt -> execute();
}catch(PDOException $e){
echo $e->getMessage();
exit();
}
  • 注意事项

参数绑定不能应用到表名上

//错误
$sth = $dbh->prepare('SELECT name, colour, calories FROM ? WHERE calories < ?');

//正确
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ?');

参数绑定不能应用到列名

//错误
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE ? < ?');

//正确
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ?');


PDO 预处理语句如何增删改查?

  • 增删改

try{
$db = new PDO($dsn,$name,$pwd);
$db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}

try{
$stmt = $db -> prepare('insert into user(name,pwd,age) values(?,?,?)');
$stmt -> execute(array('wtao','23232',14));
$count = $stmt -> rowCount();
if($count === 0){
throw new PDOException();
}

$id = $db -> lastInsertId();
}catch(PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}
try{
$db = new PDO($dsn,$name,$pwd);
$db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}

try{
$stmt = $db -> prepare('SELECT name, age, title FROM fruit WHERE id < ?');
$stmt -> execute(array(14));
while(list($name,$age,$title) = $stmt->fetch(PDO::FETCH_NUM)){

}
}catch(PDOException $e){
echo 'Connection failed: ' . $e->getMessage();
}

注意事项

  • $stmt -> execute()的返回值,如果在异常模式下,可以不用处理返回值的,只有在不是异常处理的模式下才需要判断处理

  • $db -> prepare(); 准备预处理语句都是单独的,返回PDOStatement对象也就是单独的,如果某个功能需要执行多条SQL语句,请先准备好多个PDOStatement对象,然后分别执行


    attachments-2020-10-pVDnzV115f9b6c8fef414.jpg来源:https://segmentfault.com/a/1190000010716914

  • 发表于 2020-10-30 09:30
  • 阅读 ( 522 )

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章