1. 程式人生 > >php中的PDO使用詳解

php中的PDO使用詳解

0、準備工作,建立資料表 users

CREATE DATABASE IF NOT EXISTS `test`;
USE `test`;
CREATE TABLE IF NOT EXISTS `users`(
	id 		  int unsigned  auto_increment,
	email 	  varchar(255)  not null default '',
	password  varchar(255)  not null default '',
	primary key(`id`)
)auto_increment=1,charset=utf8,engine=innodb;

1、資料庫連線
 http://php.net/manual/zh/pdo.connections.php

PDO::__construct ( string $dsn [, string $username [, string $password [, array $driver_options]]] )

$driver_options 陣列 長連線設定 PDO::ATTR_PERSISTENT=>true

$dsn = 'mysql://host=127.0.0.1;port=3306;dbname=test;charset=utf8'; // dsn
$user = 'root'; // 帳號
$pass = '';		// 密碼
$dbh = new PDO($dsn,$user,$pass);
// $dbh = new PDO($dsn,$user,$pass,[PDO::ATTR_PERSISTENT=>1]); // 長連線
var_dump($dbh);

2、執行sql語句 exec()   執行非查詢語句的sql(select ...)   返回影響的行數或者false

intPDO::exec ( string $statement )    

// 正常的非查詢操作返回影響行數
$sql = 'insert into users(email,password) value(\'[email protected]\',\''.md5('dsfsadsafasf').'\')';
$rt = $dbh->exec($sql);
var_dump($rt); // int(1)

若執行的sql不存在語法錯誤的情況下slq會執行但是影響行數為0 

如下程式碼:

// 執行查詢sql語句
$sql = 'select * from users';
// 沒有滿足wher條件的記錄 更新了0行 也就是影響了0行
$sql = 'update users set email=\'[email protected]\' where id>10000';
$rt = $dbh->exec($sql);
var_dump($rt); // int(0)

如果sql有錯誤返回false
// user表不存在 sql存在語法錯誤 返回false
$sql = 'update user set email=\'[email protected]\' where id>10000';
$rt = $dbh->exec($sql);
var_dump($rt); // bool(false)

所以判斷exec是否執行成功要用嚴格判斷 因為exec也會返回 0       $dbh->exec($sql) === false;

可以執行所有型別的sql 執行成功返回PDOStatement 物件執行 若執行錯誤返回false

publicPDO::query ( string $statement )

// 返回PDOStatement 插入更新等操作返回的不是false就是執行成功 並返回PDOStatement
$sql = 'select * from users';
$sql = 'insert into user(email,password) value(\'[email protected]\',\''.md5('123456').'\')';
$sql = 'select * from user'; // sql執行錯誤 表user不存在 返回false
$rt = $dbh->query($sql);
var_dump($rt);
foreach($rt as $key=>$val){
<span style="white-space:pre">	</span>print_r($val);
}

查詢sql若執行成功返回 物件 PDOStatement (儲存有查詢的結果資料)  foreach可以直接對返回的物件進行遍歷

執行insert update等非查詢sql 執行成功返回PDOStatement 

執行失敗query 會返回false

4、預處理的形式執行sql     這樣可防止sql注入

預處理帶有佔位符的sql字串

select * from users where id>?
select * from users where id>:id

這裡的 '?'    ':id'   都是佔位符 預處理模式會轉義這些引數防止sql注入 

publicPDO::prepare ( string $statement [, array $driver_options = array() ] )

$sql = 'select * from users where id>:id';
$stmt = $dbh->prepare($sql);
var_dump($stmt);


下面的方法是 PDOStatement類的:

繫結引數到佔位符

boolPDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )

boolPDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )

設定查詢結果的組織形式

boolPDOStatement::setFetchMode ( int $mode )

執行預處理函式

boolPDOStatement::execute ([ array $input_parameters ] )

查詢執行

獲取一條

mixedPDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT[, int $cursor_offset = 0 ]]] )

獲取所有條

arrayPDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )

示例程式碼:

$sql = 'select * from users where id>:id';
$stmt = $dbh->prepare($sql);
// bindPatam引數繫結形式
$id=1;
$stmt->bindParam('id',$id);
// 直接繫結
$stmt->bindValue('id',1);
$stmt->execute(); // 執行預處理sql
// 設定結果集資料形式
$stmt->setFetchMode(PDO::FETCH_ASSOC);
// 查詢一條資料
$rt1 = $stmt->fetch();
// 查詢全部
$rt2 = $stmt->fetchAll();
var_dump($rt1);
var_dump($rt2);

關於引數繫結:

bindValidate(key,val); 直接指定繫結的引數

a、?作為佔位符的情況

$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$stmt->bindValue(1,1);
$stmt->bindValue(2,'[email protected]');
$stmt->execute();
print_r($stmt->fetchAll());

?佔位符在繫結的時候 bindValue第一個引數指定?的序列 這個序列從1開始(而不是從零)  bindValue(n,value) 就是將value繫結到第n個?

b、以 :field 作為佔位符

$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$stmt->bindValue('id',1);
$stmt->bindValue('email','[email protected]');
$stmt->execute();
print_r($stmt->fetchAll());

bindValue 的第一個引數是 佔位符 :field 中的 field bindValue(field,value) 也就是將value繫結到佔位符為 :field 的地方

c、? 與 :key 混合的形式作為佔位符

$stmt = $dbh->prepare('select * from user where id>? and email!=:email');
$stmt->bindValue(1,1);
$stmt->bindValue('email','[email protected]');
$stmt->execute();
print_r($stmt->fetchAll());

這種形式會報錯 : Invalid parameter number: mixed named and positional parameters

bindParam(key,$value) 繫結變數到sql中

第二個引數必須是變數的引用,像bindValue一樣傳遞常量會報錯。

php5.3以後 在函式呼叫傳遞一用變數不用加 & 符了,只用在函式定義的時候對引數進行引用宣告即可

function func(&$arg){......}      func('aaa');

使用方法與bindValue類似,

$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$id = 1;
$email = '[email protected]';
$stmt->bindParam(1,$id);
$stmt->bindParam(2,$email);

$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$id = 1;
$email = '[email protected]';
$stmt->bindParam('id',$id);
$stmt->bindParam('email',$email);

execut繫結引數 execut(args_array)

在兩種不同的佔位符的情況下的繫結形式如下:

?佔位符

$stmt = $dbh->prepare('select * from user where id>? and email!=?');
$stmt->execute([1,'[email protected]']);
print_r($stmt->fetchAll());

:field 佔位符
$stmt = $dbh->prepare('select * from user where id>:id and email!=:email');
$stmt->execute(['id'=>1,'email'=>'[email protected]']);
print_r($stmt->fetchAll());

非常值得注意的一點是 bindParam() 的一個坑就是 這個函式第二個引數是引用,在foreach迴圈呼叫的時候會出現一個bug

當我們這樣使用bindParam的時候

$stmt=$dbh->prepare('select * from users where title=:title and name=:name');
$params = [':title'=>'head of artical',':name'=>'fantasy'];
foreach($params as $key=>$val){
	$stmt->bindParam($key,$val);
}

這樣繫結的結果是 select * from users where title='fantasy' and name='fantasy';

分析原因 bindParam 的第二個引數是引用型變數
分解上面的foreach 相當於:

$val = $params[':id'];
$dbh->bindParam(':id',&$val);
$val = $params[':name'];
$dbh->bindParam(':name',&$val);

同一個變數 $val 分別繫結到了 id 與 name 並且第三行修改了 $val記憶體中的值
這樣 繫結引數的兩處值也會因此改變為 第三行修改到的值

相關推薦

PHPcurl

aid ftp上傳 直接 分享圖片 tran ret 交流 init https 定義 curl是一個庫,能讓你通過URL和許多不同種的服務器進行勾搭、搭訕和深入交流,並且還支持許多協議。並且curl可以支持https認證、http post、ftp上傳、代理、cookie

PHP系列】PHP組件

命令行 分享 .cn .com function package etc quest 說我 緣起 楓爺之前做過幾年的PHP的研發,大部分都是在開源框架的引導下,編寫代碼。現在依然,本能的會去讓我使用某個PHP框架開發PHP應用,也是因為懶吧,沒有好好的去研究研究除了框架之外

JSJSON

名稱 完全 rip json詳解 core 兼容 json字符串 之間 org JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,采用完全獨立於語言的文本格式,是理想的數據交換格式。同時,JSON是 JavaScript 原生格式

nodeJsnpm

commonjs -s license mon sem console 能力 效應 模塊安裝 npm 是 Node.js 的模塊依賴管理工具。作為開發者使用的工具,主要解決開發 node.js 時會遇到的問題。如同 RubyGems 對於 Ruby 開發者和 Maven 對

PHP面試題

今天 服務 等待 速度 用途 har pda 說明 lose 自己從網上找了幾份常考到的PHP面試題進行了整理,然後才有了這份PHP面試題,並且我把所有的題目進行了詳細分析和代碼分析,希望可以對大家有幫助,謝謝大家。 這份試題我也上傳到了百度雲,有需要的可以直接去百度雲下載

006_netstatstate

51cto time list osi lose 手動 請求 等待 沒有 TCP三次握手的過程如下: 主動連接端發送一個SYN包給被動連接端; 被動連接端收到SYN包後,發送一個帶ACK和SYN標誌的包給主動連接端; 主動連接

PHP函數:call_user_func()使用方法

func instead 實例 div style bsp color can this call_user_func函數類似於一種特別的調用函數的方法,使用方法如下: <?php function nowamagic($a,$b) { echo

EditTextinputType

trac extc isa share bsp input itl 浮點 ttext <EditText Android:layout_width="fill_parent" android:layout_height="wrap_content" android

php引用 &

class www. style 輸出 ret 建立 內存空間 spa 之間 在PHP 中引用的意思是:不同的名字訪問同一個變量內容. 與C語言中的指針是有差別的.C語言中的指針裏面存儲的是變量的內容在內存中存放的地址 變量的引用 $a = 222; $b = &

linuxtop

linux查看進程之top詳解簡介top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源占用狀況,類似於Windows的任務管理器。top顯示系統當前的進程和其他狀況,是一個動態顯示過程,即可以通過用戶按鍵來不斷刷新當前狀態.如果在前臺執行該命令,它將獨占前臺,直到用戶終止該程序為止.

PHP基礎入門(一)【世界上最好用的編程語言】

轉換成 c語言 127.0.0.1 mac const 讀取 成對 後臺 isset 簡介 ---------  PHP(超文本預處器)是一種通用開源腳本語言。語法吸收了C語言、Java和Perl的特點,利於學習,使用廣泛,主要適用於Web開發領域。PHP 獨

PHPpdo的使用

stat cte 數據 bsp del host mysq dump roo <?php /** *下面代碼中information為表名 * */ //1.先要連數據庫 $pdo=new PDO(‘mysql:host=localhost;dbname=

視覺SLAM相機

目的 攝像頭 像素 一定的 原理 接收 計算 傳感 span 視覺SLAM中,通常是指使用相機來解決定位和建圖問題。 SLAM中使用的相機往往更加簡單,不攜帶昂貴的鏡頭,以一定的速率拍攝周圍的環境,形成一個連續的視頻流。 相機分類: 單目相機:只是用一個攝像頭進行SLAM的

PHP 基礎篇 - PHP 錯誤級別

ice 詳細介紹 arch fatal star use tom int error 一、前言 最近經常看到工作 2 年左右的童鞋寫的代碼也會出現以靜態方法的形式調用非靜態方法,這是個 Deprecated 級別的語法錯誤,代碼裏不應該出現的。對方很郁悶,說:為什麽我的環境

LAMP(php動態擴展模塊,httpd的rewrite,php錯誤日誌,php.ini配置

php動態擴展模塊 httpd的rewrite php錯誤日誌 php.ini配置詳解 一、php動態擴展模塊比如我們需要用到php一個模塊,恰好他沒有這個模塊。我們需要編一個.so出來?/usr/local/php/bin/php -m //查看模塊 ? 下面安裝一個redis的模塊 ? c

04-LinuxDNS(一)

訪問 舉例 dynamic linux下 目錄 col ofo 圖片 nslookup 零、關於配置Linux下的DNS中一些名詞的解釋請參見文章“03-關於配置Linux下的DNS中一些名詞的解釋(轉自網絡)”自行學習一、關於DNS配置文件查看DNS配置文件: rpm -

05-LinuxDNS(二)

相關 proc gen lin 四種方法 .... rate 我的網站 四種 接“04-Linux中DNS詳解(一)” 六、在Linux上測試域名解析1、先檢查DNS是否設置正確 cat /etc/resolv.conf [resolv.conf] # Generate

07-LinuxDNS(四)

用戶 mail all 驗證 src 更改 條目 http nslookup 接“06-Linux中DNS詳解(三)” 九、配置主從DNS服務器實現域名解析容錯 1、實驗環境zhangyujia.com(192.168.80.100)為主區域,com(192.168.8

Angular JS 指令

scope [] 功能 spa fun table clas rest 方法 Angular JS的強大功能就在於其可以自定義很多指令,現在就指令做一下詳細的剖析。 一個Angular js 指令(directive)的生命周期 開始於$compile方法 結束於$link

ES6 Promise

out 保持 type xxxxx 承諾 操作 結束 span aso Promise,簡單說就是一個容器,裏面保存著某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。 Promise 提供統一的 API