本人了个大擦-PDO(二)

  hi

明天又213了,纵然有室友3点多才睡觉的客体影响,然近来儿晚上不想学东西是本质原因。明日搞起。打算叁 、4天之内,学完PDO和AJAX那四个,还望大家没事儿来骂骂作者,免的本人又偷懒。

1、PDO

贰 、PDO对象的应用(二)

2.2 错误消息

errorCode()——错误号;

errorInfo()——错误音讯;

举个栗子

<?php
/*
* PDO错误信息
*/

$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);

$pdo->exec(‘use imooc_pdo’);
$resultd=$pdo->exec(‘delete from user where id=13’);
var_dump($resultd);
$insert=’insert user(username,password,email)
values(“Knga”,”‘.md5(‘king’).'”,”shit@shit.com”)’;
$result1=$pdo->exec($insert);
var_dump($result1);

if ($result1==false) {
echo “出错了”;
echo $pdo->errorCode();
print_r($pdo->errorInfo());
}

看一下错误音讯

Array ( [0] => 23000 [1] => 1062 [2] => Duplicata du
champ ‘Knga’ pour la clef ‘username’ )

0为不当类型,1062是代码,2是错误音信;(那里是由于username设置为了unique键,可是id号是还在增进的实在)。

2.3 query()达成查询

履行一条语句,重回贰个PDOstatement对象。

–举个栗子

<?php

/*
* PDOquery
*/

$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);

$pdo->exec(‘use imooc_pdo’);

$insert=’select * from user’;
$result1=$pdo->query($insert);
var_dump($result1);  //查看statement对象
foreach ($result1 as $row){  //查看输出结果(依据再次来到意况)
print_r($row);
}
if ($result1==false) {
echo “出错了”;
echo $pdo->errorCode();
print_r($pdo->errorInfo());
}

万一sql语句有题指标话,statement对象是false,然后前边的出口也是错误音讯;

只要sql语句正确,但询问的剧情是不设有的,那么statement对象没难点,然后输出为空。

本来如此会美观一些:

foreach ($result1 as $row){ //查看输出结果(遵照再次来到意况)
// print_r($row);echo “<br/>”;
echo ‘编号:’.$row[‘id’];echo “<br/>”;
echo ‘用户名:’.$row[‘username’];echo “<br/>”;
echo ‘密码:’.$row[‘password’];echo “<br/>”;
echo ‘邮箱:’.$row[’email’];echo “<br/>”;
echo “<hr/>”;
}

理所当然,query执行增加和删除改都以没难点的。

2.4 prepare()和execute()方法达成查询

推荐应用的查询艺术,能够达成规范查询。

prepare()——准备要推行的SQL语句,重回PDOstatement对象;

execute()——执行一条预处理语句,返回true或false;

由此地方是一对。

–举个例子

<?php
/*
* PDOprepare&execute方法
*/

$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);

$pdo->exec(‘use imooc_pdo’);

$insert=’select * from user where username=”king”‘;
$result=$pdo->prepare($insert);
var_dump($result);

$result1=$result->execute();//执行是对预处理语句
var_dump($result1);

print_r($result->fetchAll());//对statement对象才能有结果输出

 

if ($result1==false) {
echo “出错了”;
echo $pdo->errorCode();
print_r($pdo->errorInfo());
}

那里要小心预处理那种格外情况,分清楚对象到底是什么人就好办了。

–选用输出格局

要涉及数组输出或许全部照旧索引数组,有参数和方式三种区别的措施。

<?php
header(‘content-type:text/html;charset=utf-8’);
try{
$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,’root’);
$sql=’select * from user’;
$stmt=$pdo->prepare($sql);
$res=$stmt->execute();
// if($res){
//
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){//仅供给关联数组输出
// print_r($row);
// echo ‘<hr/>’;
// }
// }
// $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
// print_r($rows);
echo ‘<hr/>’;
$stmt->setFetchMode(PDO::FETCH_ASSOC);
//同样的兑现效益,用这几个措施也足以,设置默许格局

//var_dump($stmt);
$rows=$stmt->fetchAll();
print_r($rows);
}catch(PDOException $e){
echo $e->getMessage();
}

相似的大家都以想要索引数组的。

2.5 设置数据库连接属性

setAttribute()——设置数据库连接属性;

getAttribute()——得到数据库连接属性;

–举个例子

$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);
echo “自动提交”.$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);echo
“<hr/>”;
//记住pdo是个指标,所以得到属性,你懂的。然后它其中是有许多设定好的属性值的,那就是我们取得属性的前提。
echo
“私下认可的错误处理格局:”.$pdo->getAttribute(PDO::ATTRAV4_ERRMODE);echo
“<hr/>”;
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
echo “自动提交”.$pdo->getAttribute(PDO::ATT纳瓦拉_AUTOCOMMIT);echo
“<hr/>”;

下一场试着收获一大波属性消息:

$attrArr=array(
‘AUTOCOMMIT’,’ERRMODE’,’CASE’,’PERSISTENT’,’SERVER_INFO’,’SERVER_VERSION’
);
foreach ($attrArr as $attr){
echo “PDO::ATTR_$attr: “;
echo
$pdo->getAttribute(constant(“PDO::ATTR_$attr”)).”<br/>”;
}

有点是从未有过的,会有错误音信,没什么关系。

 

三 、PDOstatement对象的采用

3.1 quote()方法防止SQL注入

–SQL注入

先是举个例子表达这一个简单的SQL注入(其实作者也不是很懂——百度时而http://baike.baidu.com/link?url=jiMtgmTeePlWAqdAntWbk-wB8XKP8xS3ZOViJE9IVSToLP\_iT2anuUaPdMEM0b-VDknjolQ8BdxN8ycNLohup\_)

所谓SQL注入,正是通过把SQL命令插入到Web表单交给或输入域名或页面请求的询问字符串,最后实现诈骗服务器执行恶意的SQL命令。

为此也便是要有表单,然后需求跟数据库实行询问数据等等,然后经过恶意的利用规则上的尾巴,获得大量的,而不是页面所梦想的多少。栗子如下:

事例为记名的情状——登录要求有用户名密码等,须要与数据库中的消息举行比对;

首先是签到页面

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html>
<title>登录</title>
</head>
<body>
<form action=’doAction.php’ method=’post’>
用户名:<input type=’text’ name=’username’/><br/>
密码:<input type=’password’ name=’password’/><br/>
<input type=’submit’ value=’登录’/>
</form>
</body>
</html>

小心那里出现了表单。然后是php文件:

<?php
header(‘content-type:text/html;charset=utf-8’);
$username=$_POST[‘username’];
$password=$_POST[‘password’];
try {
$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);
$pdo->exec(‘use imooc_pdo’);
$sql=”select * from user where username='{$username}’ and
password='{$password}'”;

$stmt=$pdo->query($sql);
echo $stmt->rowCount();//呈现结果集statement对象中的行数

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

接下来浏览器中打开login.html,输入数据库中有的username和password,点击登陆,会博得1;

若输入错误的音讯,一般会获得0;

注意,若输入诸如用户名为’or
1=1#,密码轻易
,就会轻松获取数据库的拥有数据。那是由于sql语句小编的平整造成的。

于是要求过滤用户输入的音信,不要相信用户的具备操作。

–应对艺术

echo $pdo->quote($username);

写那样一句,再用上述的舞弊代码,输出会多出单引号,以及活动抬高\:

 ‘\’or 1=1#’

但如此做的话,$username的调用,会自动抬高引号,所以上面包车型地铁sql语句就要跟着变动:

$username=$pdo->quote($username);
$pdo->exec(‘use imooc_pdo’);
$sql=”select * from user where username={$username} and
password='{$password}'”;

简单来说就是把用户名上个套,对于有数据库的景况,就像都要防这些。

可是不提出利用那种手法——提出采用prepare+execute的预处理招数

3.2 预处理语句中占位符的应用

很好的警务装备流入;而且1次编写翻译即可,数次执行,减小系统的开发;

–占位符:(命名参数)(推荐)

<?php
header(‘content-type:text/html;charset=utf-8’);
$username=$_POST[‘username’];
$password=$_POST[‘password’];
try {
$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);
$pdo->exec(‘use imooc_pdo’);
$sql=”select * from user where username=:username and
password=:$password
“;
$stmt=$pdo->prepare($sql);
$stmt->execute(array(“:username”=>$username,”:password”=>$password));
//$stmt=$pdo->query($sql);
echo $stmt->rowCount();//呈现结果集statement对象中的行数

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

对应的sql语句,对应的推行,须要传递的参数也要对应的上。

–占位符?  

$sql=”select * from user where username=? and password=?”;
$stmt=$pdo->prepare($sql);
$stmt->execute(array($username,$password));

倍感?格局要不难一点,就五个点——sql语句中输入占位符+预处理+执行(传递两个数据用array)。

3.3 bindParam()方法绑定参数

把二个参数绑定到变量名。 

<?php
/*
* 绑定参数
*/

header(‘content-type:text/html;charset=utf-8’);
try {
$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);
$pdo->exec(‘use imooc_pdo’);
$sql=”insert user(username,password,email)
values(:username,:password,:email)”;

$stmt=$pdo->prepare($sql);
$username=”Wid”;$password=”123″;$email=”324@qq.com”; //定义参数
$stmt->bindParam(“:username”, $username,PDO::PARAM_STR);
$stmt->bindParam(“:password”,$password);
$stmt->bindParam(“:email”,$email);
$stmt->execute();
$res=$pdo->query(“select * from user”);
foreach ($res as $row){ //查看输出结果(依据重返情形)
// print_r($row);echo “<br/>”;
echo ‘编号:’.$row[‘id’];echo “<br/>”;
echo ‘用户名:’.$row[‘username’];echo “<br/>”;
echo ‘密码:’.$row[‘password’];echo “<br/>”;
echo ‘邮箱:’.$row[’email’];echo “<br/>”;
echo “<hr/>”;
}

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

实在便是为着不用每一回变更sql语句来实行略重复的操作。 

自然还能换个占位符

// $sql=”insert user(username,password,email) values(?,?,?)”;

// $stmt->bindParam(1,$username);

所以,总之,其实:占位符会相比较清楚,?会搅乱。

3.4 bindValue()完成绑定参数

把值绑定到参数中。

<?php

/*
* 绑定参数
*/

header(‘content-type:text/html;charset=utf-8’);
try {
$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);
$pdo->exec(‘use imooc_pdo’);
$sql=”insert user(username,password,email)
values(:username,:password,:email)”;
// $sql=”insert user(username,password,email) values(?,?,?)”;
$stmt=$pdo->prepare($sql);

//若是email参数不变
$stmt->bindValue(“:email”, ‘shit@shit.com’);
$username=”Wade”;$password=”123″;
$stmt->bindParam(“:username”, $username,PDO::PARAM_STR);
$stmt->bindParam(“:password”,$password);
$stmt->execute();
$res=$pdo->query(“select * from user”);
foreach ($res as $row){ //查看输出结果(依照重回情形)
// print_r($row);echo “<br/>”;
echo ‘编号:’.$row[‘id’];echo “<br/>”;
echo ‘用户名:’.$row[‘username’];echo “<br/>”;
echo ‘密码:’.$row[‘password’];echo “<br/>”;
echo ‘邮箱:’.$row[’email’];echo “<br/>”;
echo “<hr/>”;
}

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

行使场景正是当有个别值固定不变的时候,就能够一定变量的参数值。

3.5 bindColumn()方法绑定参数

将绑定一列到php对象。

$pdo=new PDO(‘mysql:host=localhost;dbname=imooc’,’root’,”);
$pdo->exec(‘use imooc_pdo’);
$sql=”select * from user”;
$stmt=$pdo->prepare($sql);
$stmt->execute();
//控制输出
$stmt->bindColumn(2, $username);
$stmt->bindColumn(3,$password);
$stmt->bindColumn(4,$email);
while ($stmt->fetch(PDO::FETCH_BOUND)){
echo
‘用户名:’.$username.’-密码:’.$password.’-邮箱:’.$email.'<hr/>’;
}

那边的用法正是对出口结果进行支配,利于输出格式的调节和控制。

理所当然,可以看看结果集中到底有几列,然后每一列是怎么样:

echo ‘结果集中的列数:’.$stmt->columnCount().'<hr/>’;
print_r($stmt->getColumnMeta(2));

3.6 fetchColumn()从结果集中取一列

上述的getColumnMeta()方法其实在PHP该版本中是个试验的函数,大概会在今后的本子中冲消。

$stmt->execute();

print_r($stmt->fetchColumn(3));

急需小心该措施很蛋疼的地方在于会每执行二次,指针向下一个人,所以只供给钦命第几列,但并不知道在哪一行。

3.7 debugDumpParams()打字与印刷一条预处理语句

在bindParam中测试这一个办法:

$stmt->debugDumpParams();

结果是一大堆:

SQL: [71] insert user(username,password,email)
values(:username,:password,:email) Params: 3 Key: Name: [9] :username
paramno=-1 name=[9] “:username” is_param=1 param_type=2 Key: Name:
[9] :password paramno=-1 name=[9] “:password” is_param=1
param_type=2 Key: Name: [6] :email paramno=-1 name=[6] “:email”
is_param=1 param_type=2

也等于说会交到预处理时的详细景况。

很分明正是为了Debug而生的艺术。

3.8 nextRowset()方法取出全部结果集

用来比如,mysql的存款和储蓄进度(看小编后边mysql的博文就有),一下子取出很多结果集,然后对集进行操作。

实际是指针一步步下移就好了。

事例小编懒了,不想敲了。。。。

 

尽管如此没写很多,就像是此吗。

过二日想去复查一下脚,即便还在痛,不知底还敢不敢通大便了。。。。

 

相关文章