目錄
我了个大擦-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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 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)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1319
25
PHP教程
1269
29
C# 教程
1248
24
PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? 說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

See all articles