簡體   English   中英

PDO連接和抽象類

[英]PDO Connection and abstract class

我正在使用PDO的抽象類。 我想知道是否有必要每次都$conn變量,或者當腳本結束時它是否自己這樣做?

你能告訴我,有了這種類型的結構,取消$conn的最佳方法是什么?

abstract class DB_Connection
{
    protected static $tbl_admin = "prof_admin";
    //protected static $tbl_admin = "prof_admin";

    protected static function obj_db()
    {
        $servername = "localhost";
        $username = "root";
        $password = "";
        $dbname = "salmanshahid";
        $conn = null;

        try 
        {
            $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
            // set the PDO error mode to exception
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $conn;
        }
        catch(PDOException $e)
        {
            echo $sql . "<br>" . $e->getMessage();
        } 
    }
    protected static function select($query)
    {
        try 
        {
            $conn = self::obj_db();
            $stmt = $conn->prepare($query);
            $stmt->execute();

            // set the resulting array to associative
            $stmt->setFetchMode(PDO::FETCH_ASSOC); 
            return $stmt->fetchAll();
        }
        catch(PDOException $e) 
        {
            throw new Exception("Error In SELECT STATMENT: " . $e->getMessage());
        }
    }
    protected static function insert($query)
    {
        try 
        {
            $conn = self::obj_db();
            $stmt = $conn->prepare($query);
            $stmt->execute();
        }
        catch(PDOException $e) 
        {
            throw new Exception("Error In INSERT STATMENT: " . $e->getMessage());
        }
    }

}

或者如果腳本結束時它自己這樣做了?

是的,當然,PHP會自動關閉並清理腳本執行期間打開的所有資源,因此,不必擔心手動關閉它。

無論如何,要使conn無效,只需使其無效: $this->conn = NULL ;

但是,與你班級的其他問題相比,所有這些東西都是完全可以忽略不計的,這些問題是不安全,低效和無法使用的。

  • 首先,我不知道你為什么要把這個類抽象化。 抽象類是原型類,曾經是其他類的源。 但是數據庫包裝器是一個可以使用的最終類。 我認為把它抽象化是沒有意義的。
  • 錯誤報告也是多余的和不一致的。 在錯誤消息中添加“SELECT STATMENT中的錯誤”是非常沒用的。 連接錯誤處理顯然是錯誤的。 相反,讓PDO拋出一個異常然后放手。 它的處理方式與您網站中的任何其他錯誤相同。
  • 下一個問題是安全性。 由於某些原因, select()而不是insert()函數都不支持預處理語句 ,這使得它們變得毫無用處:你可以使用PDO :: query()來獲得完全相同的結果。 但你真正需要的是通過在查詢中使用占位符同時將實際變量發送到execute()來正確使用准備/執行;
  • 另一個問題是重復代碼:兩個函數幾乎相同。
  • 同時這兩個函數都非常不可靠: select()函數僅限於一種類型的結果集,而insert()根本不返回任何內容。 相反,您可以使用單個函數來運行所有查詢,並使其返回語句,這將非常有用。 它將允許您以PDO支持的幾十種不同格式獲取返回的數據,甚至可以讓您從DML查詢中獲取受影響的行數

讓我建議你另一種方法,一個簡單的PDO包裝器,它可以讓你使用PDO最簡單和安全的方式:

<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_CHAR', 'utf8');

class DB
{
    protected static $instance = null;

    public function __construct() {}
    public function __clone() {}

    public static function instance()
    {
        if (self::$instance === null)
        {
            $opt  = array(
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES   => TRUE,
            );
            $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
            self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt);
        }
        return self::$instance;
    }

    public static function __callStatic($method, $args)
    {
        return call_user_func_array(array(self::instance(), $method), $args);
    }

    public static function run($sql, $args = [])
    {
        $stmt = self::instance()->prepare($sql);
        $stmt->execute($args);
        return $stmt;
    }
}

它功能強大,安全且易於使用。

您只需在DB::前綴后添加調用即可使用任何PDO函數:

$stmt = DB::query("SELECT * FROM table WHERE foo='bar'");

所以,首先,它是一個PDO包裝器 ,它能夠通過使用magic __call()方法運行任何PDO方法。 我添加的唯一功能是run()

讓我建議您使用一個通用run()方法,而不是您自己的不安全和不可靠的select()insert()方法,這只是這三行的簡寫:

$stmt = DB::prepare($query);
$stmt->execute($params);
$data = $stmt->fetch();

所以,你可以把它寫成一個整齊的單行:

$data = DB::run($query, $params)->fetch();

請注意,它可以運行任何類型的查詢,並以PDO支持的任何格式返回結果。

我寫了一篇關於這個簡單包裝器的文章,你可以在其中找到一些用法示例。 所有示例代碼都可以按原樣運行,只需將其復制並粘貼到腳本中並設置憑據: http//phpdelusions.net/pdo/pdo_wrapper#samples

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM