php报错 数据库密码暴露,使用pdo操作数据库,动态填充前端数据--2019年9月25日...

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'].'
';

}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 '

'.$system['copy'].' © 版权所有

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值