目录
我了个大擦-PDO(二),擦-pdo
首页 后端开发 php教程 我了个大擦-PDO(二),擦-pdo_PHP教程

我了个大擦-PDO(二),擦-pdo_PHP教程

Jul 12, 2016 am 09:03 AM
3 室友 昨天

我了个大擦-PDO(二),擦-pdo

  hi

昨天又213了,虽然有室友3点多才睡觉的客观影响,但是昨晚不想学东西是本质原因。今天搞起。打算3、4天之内,学完PDO和AJAX这两个,还望大家没事儿来骂骂我,免的我又偷懒。

1、PDO

二、PDO对象的使用(二)

2.2 错误信息

errorCode()——错误号;

errorInfo()——错误信息;

举个栗子

/*
* 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对象。

--举个栗子

/*
* 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 "
";
echo '编号:'.$row['id'];echo "
";
echo '用户名:'.$row['username'];echo "
";
echo '密码:'.$row['password'];echo "
";
echo '邮箱:'.$row['email'];echo "
";
echo "


";
}

当然,query执行增删改都是没问题的。

2.4 prepare()和execute()方法实现查询

推荐使用的查询方法,可以实现条件查询。

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

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

所以上面是一对。

--举个例子

/*
* 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());
}

这里要小心预处理这种特殊情况,分清楚对象到底是谁就好办了。

--选取输出形式

要关联数组输出或者全部或者索引数组,有参数和方法两种不同的方法。

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 '


';
// }
// }
// $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
// print_r($rows);
echo '
';
$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 "


";
//记住pdo是个对象,所以得到属性,你懂的。然后它内部是有很多设定好的属性值的,这就是我们得到属性的前提。
echo "默认的错误处理模式:".$pdo->getAttribute(PDO::ATTR_ERRMODE);echo "
";
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
echo "自动提交".$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);echo "
";

然后试着得到一大波属性信息:

$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"))."
";
}

有些是没有的,会有错误信息,没什么关系。

 

三、PDOstatement对象的使用

3.1 quote()方法防止SQL注入

--SQL注入

首先举个例子说明这个简单的SQL注入(其实我也不是很懂——百度一下http://baike.baidu.com/link?url=jiMtgmTeePlWAqdAntWbk-wB8XKP8xS3ZOViJE9IVSToLP_iT2anuUaPdMEM0b-VDknjolQ8BdxN8ycNLohup_)

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

所以也就是要有表单,然后需要跟数据库进行查询数据等等,然后通过恶意的运用规则上的漏洞,得到大量的,而不是页面所希望的数据。栗子如下:

例子为登录的情况——登录需要有用户名密码等,需要与数据库中的信息进行比对;

首先是登录页面





$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 预处理语句中占位符的使用

很好的防止注入;而且一次编译即可,多次执行,减小系统的开销;

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

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()方法绑定参数

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

/*
* 绑定参数
*/

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 "
";
echo '编号:'.$row['id'];echo "
";
echo '用户名:'.$row['username'];echo "
";
echo '密码:'.$row['password'];echo "
";
echo '邮箱:'.$row['email'];echo "
";
echo "


";
}

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

其实就是为了不用每次更改sql语句来执行略重复的操作。 

当然还可以换个占位符

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

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

所以,总之,实际上:占位符会比较清楚,?会混淆。

3.4 bindValue()实现绑定参数

把值绑定到参数中。

/*
* 绑定参数
*/

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 "
";
echo '编号:'.$row['id'];echo "
";
echo '用户名:'.$row['username'];echo "
";
echo '密码:'.$row['password'];echo "
";
echo '邮箱:'.$row['email'];echo "
";
echo "


";
}


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


';
}

这里的用法就是对输出结果进行控制,利于输出格式的调控。

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

echo '结果集中的列数:'.$stmt->columnCount().'


';
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的博文就有),一下子取出很多结果集,然后对集进行操作。

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

例子我懒了,不想敲了。。。。

 

虽然没写很多,就这样吧。

过两天想去复查一下脚,虽然还在痛,不知道还敢不敢活血了。。。。

 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1082310.htmlTechArticle我了个大擦-PDO(二),擦-pdo hi 昨天又213了,虽然有室友3点多才睡觉的客观影响,但是昨晚不想学东西是本质原因。今天搞起。打算3、4天...
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

php中的卷曲:如何在REST API中使用PHP卷曲扩展 php中的卷曲:如何在REST API中使用PHP卷曲扩展 Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

在Codecanyon上的12个最佳PHP聊天脚本 在Codecanyon上的12个最佳PHP聊天脚本 Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

解释PHP中晚期静态结合的概念。 解释PHP中晚期静态结合的概念。 Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

框架安全功能:防止漏洞。 框架安全功能:防止漏洞。 Mar 28, 2025 pm 05:11 PM

文章讨论了框架中的基本安全功能,以防止漏洞,包括输入验证,身份验证和常规更新。

自定义/扩展框架:如何添加自定义功能。 自定义/扩展框架:如何添加自定义功能。 Mar 28, 2025 pm 05:12 PM

本文讨论了将自定义功能添加到框架上,专注于理解体系结构,识别扩展点以及集成和调试的最佳实践。

如何用PHP的cURL库发送包含JSON数据的POST请求? 如何用PHP的cURL库发送包含JSON数据的POST请求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL库发送JSON数据在PHP开发中,经常需要与外部API进行交互,其中一种常见的方式是使用cURL库发送POST�...

See all articles