首頁  >  文章  >  後端開發  >  PHP 中的 PDO

PHP 中的 PDO

小云云
小云云原創
2018-03-31 09:38:3112709瀏覽

PHP PDO 是什麼?

PDO(PHP Data Objects)是一種在PHP連接資料庫的使用介面。 PDO與mysqli曾經被建議用來取代原本PHP在用的mysql相關函數,基於資料庫使用的安全性,因為後者欠缺對於SQL注入的防護。

PHP 資料物件(PDO) 擴充為PHP存取資料庫定義了一個輕量級的一致介面。實作 PDO 介面的每個資料庫驅動可以公開特定資料庫的特性作為標準擴充功能。 注意利用 PDO 擴展自身並不能實現任何資料庫功能;必須使用一個特定資料庫的 PDO 驅動來存取資料庫服務。

相關mysql影片教學推薦:《mysql教學

PDO 提供了一個資料存取抽象層,這意味著,不管使用哪種資料庫,都可以用相同的函數(方法)來查詢和取得資料。 PDO不提供資料庫抽象層;它不會重寫 SQL,也不會模擬缺少的特性。如果需要的話,應該使用一個成熟的抽象層。

資料庫支援:

  • firebird

  • #informix

  • ##informix

  • ## mysql
  • mssql
  • odbc
  • pgsql


##sqlite

PHP PDO 錯誤與錯誤處理

PDO 提供了三種不同的錯誤處理模式,以滿足不同風格的應用開發:

PDO::ERRMODE_SILENT

此為預設模式。 PDO 將只簡單地設定錯誤碼,可使用 PDO::errorCode() 和 PDO::errorInfo() 方法來檢查語句和資料庫物件。如果錯誤是由於對語句物件的呼叫而產生的,那麼可以呼叫那個物件的 PDOStatement::errorCode() 或 PDOStatement::errorInfo() 方法。如果錯誤是由於呼叫資料庫物件而產生的,那麼可以在資料庫物件上呼叫上述兩個方法。

PDO::ERRMODE_WARNING

除設定錯誤碼之外,PDO 也會發出一條傳統的 E_WARNING 訊息。如果只是想看看發生了什麼問題且不中斷應用程式的流程,那麼此設定在偵錯/測試期間非常有用。

PDO::ERRMODE_EXCEPTION

除設定錯誤碼之外,PDO 還將拋出一個 PDOException 異常類別並設定它的屬性來反射錯誤碼和錯誤訊息。此設定在偵錯期間也非常有用,因為它會有效地放大腳本中產生錯誤的點,從而可以非常快速地指出程式碼中有問題的潛在區域(記住:如果異常導致腳本終止,則交易自動回滾)。

異常模式另一個非常有用的是,相比傳統PHP 風格的警告,可以更清晰地建立自己的錯誤處理,而且比起靜默模式和明確地檢查每種資料庫呼叫的回傳值,異常模式需要的程式碼/嵌套更少。

PHP PDO 使用

連接MySQL

<?php

$type = &#39;mysql&#39;;
$hostname = &#39;localhost&#39;;
$dbname = &#39;test&#39;;
$username = &#39;root&#39;;
$password = &#39;root&#39;;

try {

    $dsn = sprintf(&#39;%s:dbname=%s;host=%s&#39;, $type, $dbname, $dbname);

    //初始化一个PDO对象
    $pdo = new PDO($dsn, $username, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION //开启异常模式
    ]);

} catch (PDOException $e) {
    die ("Database error: " . $e->getMessage());
}

?>

查詢資料

$type = &#39;mysql&#39;;
$hostname = &#39;127.0.0.1&#39;;
$dbname = &#39;test&#39;;
$username = &#39;root&#39;;
$password = &#39;root&#39;;

try {

    $dsn = sprintf(&#39;%s:dbname=%s;host=%s;charset=utf8&#39;, $type, $dbname, $hostname);

    //初始化一个PDO对象
    $pdo = new PDO($dsn, $username, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION //开启异常模式
    ]);

} catch (PDOException $e) {
    die ("Database error: " . $e->getMessage());
}

$smt = $pdo->query(&#39;SELECT * FROM t_user&#39;);

$data = $smt->fetchAll(PDO::FETCH_ASSOC);

var_dump($data);

列印結果

array(5) {
  [0]=>
  array(4) {
    ["password"]=>
    string(8) "jidasdas"
    ["phone"]=>
    string(9) "888888888"
    ["user_id"]=>
    string(32) "402881e564c0da7b0164c11adc8f0006"
    ["user_name"]=>
    string(5) "marry"
  }
  [1]=>
  array(4) {
    ["password"]=>
    string(4) "tiyv"
    ["phone"]=>
    string(6) "000000"
    ["user_id"]=>
    string(32) "402881e564c0da7b0164c1227c5d000b"
    ["user_name"]=>
    string(6) "Bliabx"
  }
  [2]=>
  array(4) {
    ["password"]=>
    string(5) "dsada"
    ["phone"]=>
    string(7) "3123123"
    ["user_id"]=>
    string(32) "402881e764bbd6340164bbd6af4e0001"
    ["user_name"]=>
    string(4) "Nusg"
  }
  [3]=>
  array(4) {
    ["password"]=>
    string(4) "kjhk"
    ["phone"]=>
    string(6) "321312"
    ["user_id"]=>
    string(32) "402881e764bbd7b60164bbd9c3cb0002"
    ["user_name"]=>
    string(6) "XIoaji"
  }
  [4]=>
  array(4) {
    ["password"]=>
    string(3) "dsa"
    ["phone"]=>
    string(3) "110"
    ["user_id"]=>
    string(32) "402881e764bbed9f0164bbee12c70000"
    ["user_name"]=>
    string(6) "Villig"
  }
}

#預處理

/* 通过数组值向预处理语句传递值 */
$sql = &#39;SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour&#39;;

$sth = $dbh->prepare($sql, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);

$sth->execute([&#39;:calories&#39; => 150, &#39;:colour&#39; => &#39;red&#39;]);

$red = $sth->fetchAll();

$sth->execute([&#39;:calories&#39; => 175, &#39;:colour&#39; => &#39;yellow&#39;]);

$yellow = $sth->fetchAll();

基本PDO 封裝

<?php
/**
* DAOPDO
* @authors by houzhyan <houzhyan@126.com>
* @blog http://www.descartes.top/
* @version >5.1 utf8
*/
class DAOPDO
{
    protected static $_instance = null;
    protected $dbName = &#39;&#39;;
    protected $dsn;
    protected $dbh;
    
    /**
     * 构造
     * 
     * @return DAOPDO
     */
    private function __construct($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)
    {
        try {
            $this->dsn = &#39;mysql:host=&#39;.$dbHost.&#39;;dbname=&#39;.$dbName;
            $this->dbh = new PDO($this->dsn, $dbUser, $dbPasswd);
            $this->dbh->exec(&#39;SET character_set_connection=&#39;.$dbCharset.&#39;, character_set_results=&#39;.$dbCharset.&#39;, character_set_client=binary&#39;);
        } catch (PDOException $e) {
            $this->outputError($e->getMessage());
        }
    }
    
    /**
     * 防止克隆
     * 
     */
    private function __clone() {}
    
    /**
     * Singleton instance
     * 
     * @return Object
     */
    public static function getInstance($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)
    {
        if (self::$_instance === null) {
            self::$_instance = new self($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset);
        }
        return self::$_instance;
    }
    
    /**
     * Query 查询
     *
     * @param String $strSql SQL语句
     * @param String $queryMode 查询方式(All or Row)
     * @param Boolean $debug
     * @return Array
     */
    public function query($strSql, $queryMode = &#39;All&#39;, $debug = false)
    {
        if ($debug === true) $this->debug($strSql);
        $recordset = $this->dbh->query($strSql);
        $this->getPDOError();
        if ($recordset) {
            $recordset->setFetchMode(PDO::FETCH_ASSOC);
            if ($queryMode == &#39;All&#39;) {
                $result = $recordset->fetchAll();
            } elseif ($queryMode == &#39;Row&#39;) {
                $result = $recordset->fetch();
            }
        } else {
            $result = null;
        }
        return $result;
    }
    
    /**
     * Update 更新
     *
     * @param String $table 表名
     * @param Array $arrayDataValue 字段与值
     * @param String $where 条件
     * @param Boolean $debug
     * @return Int
     */
    public function update($table, $arrayDataValue, $where = &#39;&#39;, $debug = false)
    {
        $this->checkFields($table, $arrayDataValue);
        if ($where) {
            $strSql = &#39;&#39;;
            foreach ($arrayDataValue as $key => $value) {
                $strSql .= ", `$key`=&#39;$value&#39;";
            }
            $strSql = substr($strSql, 1);
            $strSql = "UPDATE `$table` SET $strSql WHERE $where";
        } else {
            $strSql = "REPLACE INTO `$table` (`".implode(&#39;`,`&#39;, array_keys($arrayDataValue))."`) VALUES (&#39;".implode("&#39;,&#39;", $arrayDataValue)."&#39;)";
        }
        if ($debug === true) $this->debug($strSql);
        $result = $this->dbh->exec($strSql);
        $this->getPDOError();
        return $result;
    }
    
    /**
     * Insert 插入
     *
     * @param String $table 表名
     * @param Array $arrayDataValue 字段与值
     * @param Boolean $debug
     * @return Int
     */
    public function insert($table, $arrayDataValue, $debug = false)
    {
        $this->checkFields($table, $arrayDataValue);
        $strSql = "INSERT INTO `$table` (`".implode(&#39;`,`&#39;, array_keys($arrayDataValue))."`) VALUES (&#39;".implode("&#39;,&#39;", $arrayDataValue)."&#39;)";
        if ($debug === true) $this->debug($strSql);
        $result = $this->dbh->exec($strSql);
        $this->getPDOError();
        return $result;
    }
    
    /**
     * Replace 覆盖方式插入
     *
     * @param String $table 表名
     * @param Array $arrayDataValue 字段与值
     * @param Boolean $debug
     * @return Int
     */
    public function replace($table, $arrayDataValue, $debug = false)
    {
        $this->checkFields($table, $arrayDataValue);
        $strSql = "REPLACE INTO `$table`(`".implode(&#39;`,`&#39;, array_keys($arrayDataValue))."`) VALUES (&#39;".implode("&#39;,&#39;", $arrayDataValue)."&#39;)";
        if ($debug === true) $this->debug($strSql);
        $result = $this->dbh->exec($strSql);
        $this->getPDOError();
        return $result;
    }
    
    /**
     * Delete 删除
     *
     * @param String $table 表名
     * @param String $where 条件
     * @param Boolean $debug
     * @return Int
     */
    public function delete($table, $where = &#39;&#39;, $debug = false)
    {
        if ($where == &#39;&#39;) {
            $this->outputError("&#39;WHERE&#39; is Null");
        } else {
            $strSql = "DELETE FROM `$table` WHERE $where";
            if ($debug === true) $this->debug($strSql);
            $result = $this->dbh->exec($strSql);
            $this->getPDOError();
            return $result;
        }
    }
    
    /**
     * execSql 执行SQL语句,debug=>true可打印sql调试
     *
     * @param String $strSql
     * @param Boolean $debug
     * @return Int
     */
    public function execSql($strSql, $debug = false)
    {
        if ($debug === true) $this->debug($strSql);
        $result = $this->dbh->exec($strSql);
        $this->getPDOError();
        return $result;
    }
    
    /**
     * 获取字段最大值
     * 
     * @param string $table 表名
     * @param string $field_name 字段名
     * @param string $where 条件
     */
    public function getMaxValue($table, $field_name, $where = &#39;&#39;, $debug = false)
    {
        $strSql = "SELECT MAX(".$field_name.") AS MAX_VALUE FROM $table";
        if ($where != &#39;&#39;) $strSql .= " WHERE $where";
        if ($debug === true) $this->debug($strSql);
        $arrTemp = $this->query($strSql, &#39;Row&#39;);
        $maxValue = $arrTemp["MAX_VALUE"];
        if ($maxValue == "" || $maxValue == null) {
            $maxValue = 0;
        }
        return $maxValue;
    }
    
    /**
     * 获取指定列的数量
     * 
     * @param string $table
     * @param string $field_name
     * @param string $where
     * @param bool $debug
     * @return int
     */
    public function getCount($table, $field_name, $where = &#39;&#39;, $debug = false)
    {
        $strSql = "SELECT COUNT($field_name) AS NUM FROM $table";
        if ($where != &#39;&#39;) $strSql .= " WHERE $where";
        if ($debug === true) $this->debug($strSql);
        $arrTemp = $this->query($strSql, &#39;Row&#39;);
        return $arrTemp[&#39;NUM&#39;];
    }
    
    /**
     * 获取表引擎
     * 
     * @param String $dbName 库名
     * @param String $tableName 表名
     * @param Boolean $debug
     * @return String
     */
    public function getTableEngine($dbName, $tableName)
    {
        $strSql = "SHOW TABLE STATUS FROM $dbName WHERE Name=&#39;".$tableName."&#39;";
        $arrayTableInfo = $this->query($strSql);
        $this->getPDOError();
        return $arrayTableInfo[0][&#39;Engine&#39;];
    }
    //预处理执行
    public function prepareSql($sql=&#39;&#39;){
        return $this->dbh->prepare($sql);
    }
    //执行预处理
    public function execute($presql){
        return $this->dbh->execute($presql);
    }
 
/**
 * pdo属性设置
 */
    public function setAttribute($p,$d){
        $this->dbh->setAttribute($p,$d);
    }
 
    /**
     * beginTransaction 事务开始
     */
    public function beginTransaction()
    {
        $this->dbh->beginTransaction();
    }
    
    /**
     * commit 事务提交
     */
    public function commit()
    {
        $this->dbh->commit();
    }
    
    /**
     * rollback 事务回滚
     */
    public function rollback()
    {
        $this->dbh->rollback();
    }
    
    /**
     * transaction 通过事务处理多条SQL语句
     * 调用前需通过getTableEngine判断表引擎是否支持事务
     *
     * @param array $arraySql
     * @return Boolean
     */
    public function execTransaction($arraySql)
    {
        $retval = 1;
        $this->beginTransaction();
        foreach ($arraySql as $strSql) {
            if ($this->execSql($strSql) == 0) $retval = 0;
        }
        if ($retval == 0) {
            $this->rollback();
            return false;
        } else {
            $this->commit();
            return true;
        }
    }
 
    /**
     * checkFields 检查指定字段是否在指定数据表中存在
     *
     * @param String $table
     * @param array $arrayField
     */
    private function checkFields($table, $arrayFields)
    {
        $fields = $this->getFields($table);
        foreach ($arrayFields as $key => $value) {
            if (!in_array($key, $fields)) {
                $this->outputError("Unknown column `$key` in field list.");
            }
        }
    }
    
    /**
     * getFields 获取指定数据表中的全部字段名
     *
     * @param String $table 表名
     * @return array
     */
    private function getFields($table)
    {
        $fields = array();
        $recordset = $this->dbh->query("SHOW COLUMNS FROM $table");
        $this->getPDOError();
        $recordset->setFetchMode(PDO::FETCH_ASSOC);
        $result = $recordset->fetchAll();
        foreach ($result as $rows) {
            $fields[] = $rows[&#39;Field&#39;];
        }
        return $fields;
    }
    
    /**
     * getPDOError 捕获PDO错误信息
     */
    private function getPDOError()
    {
        if ($this->dbh->errorCode() != &#39;00000&#39;) {
            $arrayError = $this->dbh->errorInfo();
            $this->outputError($arrayError[2]);
        }
    }
    
    /**
     * debug
     * 
     * @param mixed $debuginfo
     */
    private function debug($debuginfo)
    {
        var_dump($debuginfo);
        exit();
    }
    
    /**
     * 输出错误信息
     * 
     * @param String $strErrMsg
     */
    private function outputError($strErrMsg)
    {
        throw new Exception(&#39;MySQL Error: &#39;.$strErrMsg);
    }
    
    /**
     * destruct 关闭数据库连接
     */
    public function destruct()
    {
        $this->dbh = null;
    }
   /**
    *PDO执行sql语句,返回改变的条数
    *如需调试可选用execSql($sql,true)
    */
    public function exec($sql=&#39;&#39;){
        return $this->dbh->exec($sql);
    }
}
?>

PHP PDO 詳細說明

PDO 類別

# PDO::beginTransaction — 啟動一個交易

PDO::commit — 提交一個交易

PDO::__construct — 建立一個表示資料庫連線的PDO 實例

#PDO:: errorCode — 取得跟資料庫句柄上一次操作相關的SQLSTATE

PDO::errorInfo — 傳回最後一次操作資料庫的錯誤訊息

PDO::exec — 執行一則SQL 語句,並傳回受影響的行數PDO::getAttribute — 取回一個資料庫連接的屬性

PDO::getAvailableDrivers — 傳回一個可用驅動的陣列

#PDO::inTransaction —檢查是否在一個交易內

PDO::lastInsertId — 傳回最後插入行的ID或序列值

PDO::prepare — 備要執行的SQL語句並傳回一個PDOStatement 物件

PDO::query — 執行SQL 語句,傳回PDOStatement物件,可以理解為結果集

PDO::quote — 為SQL語句中的字串加上引號。

PDO::rollBack — 回溯一個事務

PDO::setAttribute — 設定屬性

PDOStatement 類別

#PDOStatement: :bindColumn — 綁定一列到一個PHP 變數

PDOStatement::bindParam — 綁定一列到一個PHP 變數

###PDOStatement::bindParam — 綁定一個參數到指定的變數名稱######PDOStatement::bindValue — 把一個值綁定到一個參數# #####PDOStatement::closeCursor — 關閉遊標,使語句能再次執行。 ######PDOStatement::columnCount — 傳回結果集中的列數######PDOStatement::debugDumpParams — 列印一個SQL 預處理指令######PDOStatement::errorCode — 取得跟上語句句柄操作相關的SQLSTATE######PDOStatement::errorInfo — 取得跟上語句句柄操作相關的擴充錯誤訊息######PDOStatement::execute — 執行一條預處理語句###### PDOStatement::fetch — 從結果集中取得下一行######PDOStatement::fetchAll — 傳回一個包含結果集中所有行的陣列######PDOStatement::fetchColumn — 從結果集的下一行返回單獨的一列。 ###

PDOStatement::fetchObject — 取得下一行並以一個物件傳回。

PDOStatement::getAttribute — 擷取一個語句屬性

PDOStatement::getColumnMeta — 傳回結果集中一列的元資料

PDOStatement::nextRowset — 在一個多行集語句句柄中推進到下一個行集

PDOStatement::rowCount — 傳回受上一個SQL 語句影響的行數

PDOStatement::setAttribute — 設定一個語句屬性

# PDOStatement::setFetchMode — 為語句設定預設的取得模式。

以上是PHP 中的 PDO的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn