1. 程式人生 > >PHP的預處理語句的使用

PHP的預處理語句的使用

很多更成熟的資料庫都支援預處理語句的概念。
什麼是預處理語句?
可以把它看作是想要執行的 SQL 的一種編譯過的模板,它可以使用變數引數進行定製。預處理語句可以帶來兩大好處: 
•  查詢僅需解析(或預處理)一次,但可以用相同或不同的引數執行多次。當查詢準備好後,資料庫將分析、編譯和優化執行該查詢的計劃。對於複雜的查詢,此過程要花費較長的時間,如果需要以不同引數多次重複相同的查詢,那麼該過程將大大降低應用程式的速度。通過使用預處理語句,可以避免重複分析/編譯/優化週期。簡言之,預處理語句佔用更少的資源,因而執行得更快。  
•  提供給預處理語句的引數不需要用引號括起來,驅動程式會自動處理。如果應用程式只使用預處理語句,可以確保不會發生SQL 注入。(然而,如果查詢的其他部分是由未轉義的輸入來構建的,則仍存在 SQL 注入的風險)。  

預處理語句如此有用,以至於它們唯一的特性是在驅動程式不支援的時PDO 將模擬處理。這樣可以確保不管資料庫是否具有這樣的功能,都可以確保應用程式可以用相同的資料訪問模式。

例如:

<?php

/**
 * 我直接針對PDO的封裝類
 * User: seven
 * Date: 2017/7/26
 * Time: 9:43
 */
class MyPDO
{
    /** 訪問資料庫的PDO物件 */
    protected $pdo;

    /**
     * 當前類的建構函式
     * 讀取資料庫配置資訊檔案(自己設定的),並初始化PDO物件
     */
    function __construct()
    {
        if(file_exists('db.ini')){
            $arr = parse_ini_file('db.ini');
        }else{
            exit('沒有找到對應的資料庫配置檔案資訊 ...');
        }
        $dsn = "{$arr['dbms']}:dbname={$arr['dbname']};host={$arr['host']};port={$arr['port']};charset={$arr['charset']}";
        $user = $arr['user'];
        $password = $arr['password'];
        $this->pdo = new PDO($dsn,$user,$password);
    }

    /**
     * 銷燬自己的操作類時,同時銷燬被建立了的PDO物件
     */
    function __destruct()
    {
        $this->pdo = null;
    }

    /**
     * 執行DML操作語句
     * @param $sql     需要執行的SQL語句
     * @return int     返回執行語句後受到影響的行數
     */
    public function pdoExec($sql){
        return $this->pdo->exec($sql);
    }

    /**
     * 返回結果為陣列結構
     * @param $sql        需要執行的SQL語句
     * @param int $var    執行query函式的引數(可選值:PDO::FETCH_BOTH(預設),PDO::FETCH_NUM,PDO::FETCH_ASSOC)
     * @return array      將結果轉換為陣列並返回,如果沒有查詢結果則返回一個空陣列
     */
    public function arrayByPdoQuery($sql, $var=PDO::FETCH_BOTH){
        $ps = $this->pdo->query($sql, $var);
        if($ps)
            return $ps->fetchAll();
        return array();
    }

    /**
     * 獲取查詢結果並封裝為一個物件陣列
     * @param $sql                  需要執行的SQL語句
     * @param string $class_name    建立類的名稱
     * @param array $ctor_args      此陣列的元素被傳遞給對應類的建構函式
     * @return array                返回組裝好的物件陣列
     */
    public function objectByPdoQuery($sql, $class_name='stdClass', $ctor_args=array()){
        $ps = $this->pdo->query($sql);
        $arr = array();
        if($ps){
            while ($obj = $ps->fetchObject($class_name, $ctor_args)){
                array_push($arr, $obj);
            }
        }
        return $arr;
    }

    /**
     * 使用PDO預編譯語句執行DML操作並返回受影響的行數
     * @param $sql           需要執行的SQL語句(預編譯語句寫法)
     * @param array $arr     預編譯語句需要新增的資料值,陣列結構
     * @return int           返回DML執行後受影響的行數
     */
    public function intByPdoPrepare($sql, array $arr=array()){
        $ps =$this->pdo->prepare($sql);
        $ps->execute($arr);
        return $ps->rowCount();
    }

    /**
     * 使用PDO預編譯語句執行查詢操作並返回結果集合
     * @param $sql           需要執行的SQL語句(預編譯語句寫法)
     * @param array $arr     預編譯語句需要新增的資料值,陣列結構
     * @return array         轉換為陣列結構的返回值結果
     */
    public function arrayByPdoPrepare($sql, array $arr=array()){
        $ps =$this->pdo->prepare($sql);
        $ps->execute($arr);
        if($ps)
            return $ps->fetchAll();
        return array();
    }

    /**
     * 獲取查詢結果並封裝為一個物件陣列
     * @param $sql                  需要執行的SQL語句
     * @param array $arr            預編譯語句需要新增的資料值,陣列結構
     * @param string $class_name    建立類的名稱
     * @param array $ctor_args      此陣列的元素被傳遞給對應類的建構函式
     * @return array                返回組裝好的物件陣列
     */
    public function objectByPdoPrepare($sql, array $arr=array(), $class_name='stdClass', $ctor_args=array()){
        $ps =$this->pdo->prepare($sql);
        $ps->execute($arr);
        $arr = array();
        if($ps){
            while ($obj = $ps->fetchObject($class_name, $ctor_args)){
                array_push($arr, $obj);
            }
        }
        return $arr;
    }

}




<?php
/**
 * Created by PhpStorm.
 * User: seven
 * Date: 2017/7/27
 * Time: 13:18
 */

include_once 'MyPDO.class.php';
//include_once 'Student.class.php';

$mp = new MyPDO();
$sex = 'male';
//$sql = "select * from student where ssex=?";
//$arr = $mp->objectByPdoQuery($sql, 'Student');
//var_dump($arr);

$sql = "insert into student values (null,?,?,?,?,?,?)";
$params = array(
    'xxx','male','xx-xx-xx','xxx','xxxxxxxx','xxxxxxx'
);
$num = $mp->intByPdoPrepare($sql, $params);
echo $num.'<br>';

$sql = "select * from student where ssex=?";
$arr = $mp->objectByPdoPrepare($sql,array($sex),'Student');
var_dump($arr);