0x01 PDO概念
PDO::(Php Data Object) php数据对象,他统一了PHP访问各种类型数据库的访问方式。简单说就是,只要提供正确的数据库类型与相应的成功连接,PDO就能用基本的数据库语句来操作数据库,减少了不同数据库间语法的差异带来的麻烦。
0x02 PDO创建数据库连接
对于使用PDO连接数据库有几点知值得注意的地方:
1. 由于PDO是一个对象,他需要被new出来,而不是像使用函数一样直接调用函数即可。
2. 使用PDO对象需要提供三个必需的参数:
(1)连接的数据源:‘类型:host=ip地址;dbname=数据库名’。类型:这指的是所要连接的数据库类型;IP地址:指的是数据库所在地的ip,如果是本地就是环回口地址127.0.0.1。如果使用了云数据库或数据库搭建在了其他服务器上,那么相应的IP地址就是数据库所在的服务器的公网ip;数据库名:这指的是要使用的数据库名。由于PDO一次只能连接一个数据库,所以需要提供准确的数据库名。
(2)账号:连接相应数据库所要提供的账号。(对于mysql来说,有一个默认账号是root)
(3)密码:连接相应数据库所要提供的密码。(对于mysql来说,默认账号root的默认密码是root)
3. 连接数据库时要try-catch,防止连接错误时错误信息回显到浏览器页面上。如果直接展示报错信息,会暴露数据库等重要信息,有心人可能会加以利用。
$db = [ 'type'=>'mysql', 'host'=>'127.0.0.1', 'dbname'=>'test', 'username'=>'root', 'password'=>'root' ]; // 1.连接的数据源: // 类型:host=ip地址;dbname=数据库名 // 2.账号 // 3.密码 // 拼接字符串 $dsn = $db['type'].':host='.$db['host'].';dbname='.$db['dbname']; // 连接数据库时要try-catch,防止连接错误时错误信息回显到浏览器页面上 try{ $pdo =new PDO($dsn, $db['username'], $db['password']); }catch(PDOException $e){ // die:输出错误信息并结束进程 die('Connection Failed : '. $e->getMessage()); }
0x03 PDO操作数据库
对于PDO操作数据库首先要明确两个对象:
1. $pdo =new PDO($dsn, $db['username'], $db['password']); 第一个,通过new PDO()所获取的对象$pdo(这里的变量名可以随意命名)
2. $stmt = $pdo->prepare($sql); 第二个,通过$pdo对象的预处理函数prepare()所获取的对象$stmt(这里的变量名可以随意命名)
以上两个对象各自拥有的可调用函数不同,注意不要弄混。
下面来聊聊增删改查操作:
1. sql语句:在sql语句中我们可以使用占位符来实现sql语句的复用,这里的占位符用 : (冒号)进行标识。例如:
$insert_sql = 'insert into user (`id`,`name`,`age`,`desc`) values (:id,:name,:age,:desc)';
2. 既然我们在sql语句中使用了占位符,那我们就需要在占位符上填充正确的数据,这就是PDO绑定参数:
$stmt->bindParam('id',$data['id'],PDO::PARAM_INT); $stmt->bindParam('name',$data['name']); $stmt->bindParam('age',$data['age']); $stmt->bindParam('desc',$data['desc']);
使用$stmt对象的bindParam()方法进行参数绑定,然后这个方法有两个必需参数:
(1)占位符的名称
(2)该占位符需要赋予的值。注意:这里的值必须是一个已定义的变量,如果直接写上一个字符串或数字会有报错,这警告应该是为了方便复用.
(3)第三个参数是可选参数,提供一个系统的预定义变量来说明前一个变量的数据类型;有三种常用值:
PDO::PARAM_INT: 整数类型
PDO::PARAM_STR: 字符串类型
PDO::FETCH_ASSOC: 获取结果集中的关联部分
注意:这里只是绑定参数,不意味着给参数赋了值。真正用上参数值是执行数据库语句时。
3. 执行sql语句,这里的返回值bool,可以用于判断是否成功
$stmt->execute()
4. 下面是一些PDOStatement类(即$stmt)常用方法:
execute(): 执行SQL语句(读/写)
rowCount(): 返回受影响的记录数量(不适合SELECT,因为select只执行查询)
errorInfo(): 返回错误信息数组
fetch(): 获取结果集中的下一行(一维数组)
fetchAll(): 返回结果集中的所有行(二维数组,常配合foreach使用;提供两种下标:$key 和 数字)
fetchColumn(): 返回结果集下一行的单独的一列
bindColumn(): 将结果集某字段绑定到指定变量上
0x04 实践
准备工作:创建一个用于连接数据库的文件connect.php:
<?php $db = [ 'type'=>'mysql', 'host'=>'127.0.0.1', 'dbname'=>'test', 'username'=>'root', 'password'=>'root' ]; $dsn = $db['type'].':host='.$db['host'].';dbname='.$db['dbname']; try{ $pdo = new PDO($dsn, $db['username'], $db['password']); }catch(PDOException $e){ die('Connection Failed : '. $e->getMessage()); } ?>
1. 将原本的数组数据插入到数据库中(仅展示一个实例):
// 2.创建sql语句 $mov_insert = 'insert into movies (`name`,`image`,`detail`,`cate_id`) values (:name,:image,:detail,:cate_id)'; // 3.预处理 $stmt = $pdo->prepare($mov_insert); foreach($movies as $movie){ // 4.绑定变量 $stmt->bindParam('name', $movie['name']); $stmt->bindParam('image', $movie['image']); $stmt->bindParam('detail', $movie['detail']); $stmt->bindParam('cate_id', $movie['cate_id']); // 5.执行sql语句 if($stmt->execute()){ echo '成功插入'.$movie['mov_id'].'<br>'; }else{ die('发生错误'.$stmt->errorInfo()); } }
2. 将数据从数据库中读取出来并用变量保存(仅展示一个实例):
// 2.创建sql语句 $movie_select = 'select * from movies'; $cate_select = 'select * from cates'; $comment_select = 'select * from comments'; $user_select = 'select * from users'; $system_select = 'select * from system'; // 3.预处理 $stmt = $pdo->prepare($movie_select); // 5.执行sql语句 if($stmt->execute()){ $movies = $stmt->fetchAll(PDO::FETCH_ASSOC); //while($movies = $stmt->fetch(PDO::FETCH_ASSOC)){ //echo 111; //$movies = $stmt->fetch(PDO::FETCH_ASSOC); //print_r($movies); //} //print_r($movies); }else{ die('发生错误'.$stmt->errorInfo()); }
注意:
(1)fetchAll和fetch都可以用来处理取出的数据,但fetch要与while配合使用。还有一点,比如while($movies = $stmt->fetch(PDO::FETCH_ASSOC))中,循环到最后一次$movies被赋值为false,这导致了外部无法再利用$movies。还有就是每循环一次,$movies的值都会被覆盖。
(2)当取数据的数据库里只有一条数据时,请使用fetch,使用fetchAll会出错。因为,fetch取出的数据是一维数组,fetchAll取出的数据相当于foreach循环中的value值,即相当于二维数组的内层。
3. 修改footer.php:
<?php include __DIR__.'/connect.php'; $stmt = $pdo->prepare($system_select); // 5.执行sql语句 if($stmt->execute()){ $system = $stmt->fetch(PDO::FETCH_ASSOC); }else{ die('发生错误'.$stmt->errorInfo()); } // <!--底部版权--> echo '<div class="footer"> <p class="copyright">'.$system['copy'].' © 版权所有</p> </div> </body> </html>'; ?>
效果:
0x05 总结
1. 创建数据库的基本流程:
(1)连接数据库,创建pdo对象
$pdo = new PDO($dsn, $username, $password);
(2)创建sql语句$sql
(3)预处理SQL语句对象: $stmt = $pdo->prepare($sql)
(4)[可选]如果sql语句使用了占位符,要进行参数绑定
(5)执行SQL查询: $stmt->execute()
2. 获取数据库数据进行判断时,要注意数据的类型,慎用===