php之PDO連接mysql數據庫,增刪改查等等操作實例


我們使用傳統的 mysql_connect 、mysql_query方法來連接查詢數據庫時,如果過濾不嚴就有SQL注入風險,導致網站被攻擊。

雖然可以用mysql_real_escape_string()函數過濾用戶提交的值,但是也有缺陷。

而使用PHP的PDO擴展的 prepare 方法,就可以避免sql injection 風險。

PDO(PHP Data Object) 是PHP5新加入的一個重大功能,因為在PHP 5以前的php4/php3都是一堆的數據庫擴展來跟各個數據庫的連接和處理.

如 php_mysql.dll。 PHP6中也將默認使用PDO的方式連接,mysql擴展將被作為輔助 。

官方:http://php.net/manual/en/book.pdo.php

 

1、使用PDO連接前需要先確認PDO擴展是否已經打開。

        使用PDO擴展之前,先要啟用這個擴展,PHP.ini中。

去掉"extension=php_pdo.dll"前面的";"號,若要連接數據庫,還需要去掉與PDO相關的數據庫擴展前面的";"號。

(一般用的是php_pdo_mysql.dll),然后重啟Apache服務器即可。 

extension=php_pdo.dll
extension=php_pdo_mysql.dll

2、PDO連接數據庫:

 
         
class MysqlPdo
{
private $config = [
// 數據庫類型
'type' => 'mysql',
// 服務器地址
'hostname' => '127.0.0.1',
// 數據庫名
'database' => 'test',
// 用戶名
'username' => 'root',
// 密碼
'password' => 'root',
// 端口
'hostport' => '3306',
// 數據庫編碼默認采用utf8
'charset' => 'utf8',
];
private $pdo;

public function __construct()
{
$dsn = "{$this->config['type']}:host={$this->config['hostname']};";
$dsn.= "dbname={$this->config['database']};charset={$this->config['charset']}";
$pdo = new PDO($dsn, $this->config['username'], $this->config['password']);
$pdo->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->pdo = $pdo;
unset($dsn);
}
public function select($sql = '')
{
$res = $this->pdo->query($sql);
$res = $res->fetchAll(PDO::FETCH_ASSOC);
return $res;
}
}
 
        

3、PDO設置屬性:

 PDO有三種錯誤處理方式:

1、PDO::ERrmODE_SILENT 不顯示錯誤信息,只設置錯誤碼

2、PDO::ERrmODE_WARNING 顯示警告錯

3、PDO::ERrmODE_EXCEPTION 拋出異常

1
$pdo->setAttribute(\PDO::ATTR_ERrmODE, \PDO::ERrmODE_EXCEPTION);

1) :當設置為PDO::ERrmODE_SILENT時可以通過調用errorCode() 或errorInfo()來獲得錯誤信息,當然其他情況下也可以。

2) :因為不同數據庫對返回的字段名稱大小寫處理不同,所以PDO提供了PDO::ATTR_CASE設置項(包括PDO::CASE_LOWER,PDO::CASE_NATURAL,PDO::CASE_UPPER),來確定返回的字段名稱的大小寫。

3) :通過設置PDO::ATTR_ORACLE_NULLS類型(包括PDO::NULL_NATURAL,PDO::NULL_EmpTY_STRING,PDO::NULL_TO_STRING)來指定數據庫返回的NULL值在php中對應的數值。

 

4、PDO常用方法及其應用:

 

PDO::query() 主要是用於有記錄結果返回的操作,特別是SELECT操作

PDO::exec() 主要是針對沒有結果集合返回的操作,如INSERT、UPDATE等操作

PDO::prepare() 主要是預處理操作,需要通過$rs->execute()來執行預處理里面的SQL語句,這個方法可以綁定參數,功能比較強大(防止sql注入就靠這個)

PDO::lastInsertId() 返回上次插入操作,主鍵列類型是自增的最后的自增ID

PDOStatement::fetch() 是用來獲取一條記錄

PDOStatement::fetchAll() 是獲取所有記錄集到一個集合

PDOStatement::fetchColumn() 是獲取結果指定第一條記錄的某個字段,缺省是第一個字段

PDOStatement::rowCount() 主要是用於PDO::query()和PDO::prepare()進行DELETE、INSERT、UPDATE操作影響的結果集,對PDO::exec()方法和SELECT操作無效。

 

5、PDO操作實例:

 

【示例6,說明】,防sql注入操作:

 

1、使用PDO訪問MySQL數據庫時,真正的real prepared statements 默認情況下是不使用的。

為了解決這個問題,你必須禁用 prepared statements的仿真效果。

2、設置禁用prepared statements:$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); 

 

它會告訴PDO禁用模擬預處理語句,並使用 real parepared statements 。

這可以確保SQL語句和相應的值在傳遞到mysql服務器之前是不會被PHP解析的(禁止了所有可能的惡意SQL注入攻擊)。

雖然你可以配置文件中設置字符集的屬性(charset=utf8),但是需要格外注意的是,老版本的 PHP( < 5.3.6)在DSN中是忽略字符參數的。

 

但是我們需要注意以下幾種情況,PDO並不能幫助我們防范SQL注入的:

1、你不能讓占位符 ? 代替一組值,如:

select * from xc_company where id in( ? );

2、你不能讓占位符代替數據表名或列名,如:

select * from xc_company order by ?;

3、你不能讓占位符 ? 代替任何其他SQL語法,如:

select EXTRACT( ? from date) as times from xc_company;

查看PDO都有那些方法

echo '<pre>';
print_r(get_class_methods('PDO'));
echo '</pre>';

結果:

Array
(
    [0] => __construct
    [1] => prepare
    [2] => beginTransaction
    [3] => commit
    [4] => rollBack
    [5] => inTransaction
    [6] => setAttribute
    [7] => exec
    [8] => query
    [9] => lastInsertId
    [10] => errorCode
    [11] => errorInfo
    [12] => getAttribute
    [13] => quote
    [14] => __wakeup
    [15] => __sleep
    [16] => getAvailableDrivers
)

常用實例源碼:

<?php
 
# 【PDO連接mysql數據庫】(數據庫名:lmgg ,賬戶:root,密碼:root)
$pdo = new \PDO('mysql:host=localhost;dbname=lmgg;charset=utf8','root','root'); 
# 設置數據庫編碼為utf-8(防止亂碼)當然上面的連接設置了。
# 上面可設置也可不設置,有沒有charset=utf8都可以連接上數據庫
$pdo->exec('set names utf8'); 
 
 
 
 
 
# 【示例1:查詢數據】:查詢company表中的id和name字段。存到$data數組中去
$res = $pdo->query("select id,name from xc_company"); 
$data = [];
 
# 1:FETCH_ASSOC   關聯數組形式返回 
# 2:FETCH_NUM     數字索引數組形式返回
# 設置返回數據類型方法1:
$res->setFetchMode(\PDO::FETCH_NUM); 
while($row = $res->fetch()){
    $data[] = $row;
}
echo '<pre>';
print_r($data);
echo '</pre>';
 
# 設置返回數據類型方法2:
while($row = $res->fetch(\PDO::FETCH_ASSOC)){
    $data[] = $row;
}
echo '<pre>';
print_r($data);
echo '</pre>';
 
 
 
 
# 【示例2:添加數據】:添加數據到company表中,並返回數據在表中的ID是多少!
$res = $pdo->exec("insert into xc_company(name) values('小川編程添加111')");
if($res){
    echo '11添加成功數據ID為:'.$pdo->lastinsertid().'<br/>';
}
$res = $pdo->query("insert into xc_company(name) values('小川編程添加222')");
if($res){
    echo '22添加成功數據ID為:'.$pdo->lastinsertid().'<br/>';
}
 
 
 
 
 
# 【示例3:更新數據】:
$res = $pdo->exec("update xc_company set name='小川編程更新111' where id=26");
if($res){
    echo '更新數據成功<br/>';
}
$res = $pdo->query("update xc_company set name='小川編程更新222' where id=26");
if($res){
    echo '成功更新數據【'.$res->rowCount().'】條<br/>';
}
 
 
 
 
 
 
# 【示例4:刪除數據】:
$res = $pdo->exec("delete from xc_company where id=38");
if($res){
    echo '刪除數據成功<br/>';
}
$res = $pdo->query("delete from xc_company where id=38");
if($res){
    echo '成功刪除數據【'.$res->rowCount().'】條<br/>';
}
 
 
 
 
 
# 【示例5:統計數據】:統計company表有多少條數據
$num = $pdo->query("select count(*) from xc_company");
echo '共有數據:【'.$num->fetchColumn().'】條';
 
 
 
 
 
# 【示例6:防sql注入】:實例,使用前先看文字說明,會理解的更透徹!
#  PDO連接mysql數據庫(數據庫名:lmgg ,賬戶:root,密碼:root)
$pdo = new \PDO("mysql:host=localhost; dbname=lmgg", "root", "root");
#  禁用prepared statements的仿真效果
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); 
$pdo->query("set names 'utf8'");
$sql="select * from xc_company where name = ?";
$res = $pdo->prepare($sql);
$name = '小川編程';
$exeres = $res->execute(array($name));
$data = [];
if($exeres){
    while ($row = $res->fetch(\PDO::FETCH_ASSOC)){
       $data[] = $row;
    }
}
echo '<pre>';
print_r($data);
echo '</pre>';
$pdo = null;
 
?>
$dsn= "{$this->config['type']}:host={$this->config['hostname']};";
$dsn.= "dbname={$this->config['database']};charset={$this->config['charset']}";
$pdo = new PDO($dsn, $this->config['username'], $this->config['password']);

如果有幫到您,就給小編打個賞吧,謝謝哦!




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM