PHP设计OO数据库连接

时间:2013-06-28 04:03:49

标签: php oop

所以,我正在开发一个需要数据库连接的项目。我选择使用PDO来实现其多功能性,并且需要弄清楚如何设置连接。目前我正在寻找这样的事情:

class Database {
  private static $db;
    static function initDB() {
      if(!is_object(self::$db) || get_class(self::$db) != 'PDO') {
        include('core/db.php');
        try {
            $db = new PDO($database, $username, $password);
        } catch(PDOException $e) {
            print("<br />Could not establish database connection. Error message: ".$e->getMessage()."<br />");
            die();
        }
    }
    //Try the transaction
    /*
    if($transaction = $db::query(PDO::quote($value)))
        $db::query(PDO::quote("INSERT INTO log VALUES ('".Authorization::$user."','".PDO::quote($value)."', 'Success')"));
    else
        $db::query(PDO::quote("INSERT INTO log VALUES ('".Authorization::$user."','".PDO::quote($value)."', 'Failure')"));*/
 }
}

所以,这几乎揭示了我不知道的一个概念:单例和静态类/对象。使用通过某种OO方法通过脚本初始化的__construct最佳做法设置数据库连接的方法吗?

2 个答案:

答案 0 :(得分:1)

数据库连接不应该是静态的还是单例的。这仅仅引入了另一种形式的全局状态,这对于单元测试是不利的,并且隐藏了明显的依赖性。

这里正确的方法是将PDO的实例注入需要它的类中。您遵守单一责任原则依赖注入

  
    

注意,您应该从不记录错误,并在include()构造函数中执行PDOAdapter,因为它掩盖了对单一责任原则的违反

  

所以,这看起来像这样:

final class PDO_Provider extends PDO
{
    /**
     * Constructor. Inits PDO 
     * 
     * @param array $params
     * @return void
     */
    public function __construct(array $params)
    {
        try {

            extract($params);

            parent::__construct(sprintf('mysql: host=%s; dbname=%s', $host, $database), $user, $password);

            $this->setAttribute(parent::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES UTF8');
            $this->setAttribute(parent::ATTR_ERRMODE, parent::ERRMODE_EXCEPTION);
            $this->setAttribute(parent::ATTR_EMULATE_PREPARES, false);
            $this->setAttribute(parent::ATTR_DEFAULT_FETCH_MODE, parent::FETCH_ASSOC);

        } catch(PDOException $e) {

            die($e->getMessage());
        }
    }
}

你会像这样使用它,

<?php


$sql_config = array(
    'host'          =>  'localhost',
    'user'          =>  'root',
    'password'      =>  '',
    'database'      =>  '_DB_NAME_',
);

// <- Or you can include that, like 
$sql_config = include(__DIR__ . '/core/db_params.php');

$pdoProvider = new PDO_Provider($sql_config);

$user = new User_Login($pdoProvider); // the point here is to inject an instance of $pdoProvider. User_Login is actually irrelevant

答案 1 :(得分:-1)

如果您想使用普通对象而不是单例,请尝试以下方法:

class PDOConnector{

    protected $connection;

    function __construct($host, $user, $pass, $db_name)
    {
        //create database connection
        try{
            $this->connection = new PDO('mysql:host='.$this->host.';dbname='.$this->db_name.';charset=utf8', $this->user, $this->pass,array(PDO::ATTR_EMULATE_PREPARES => false, 
                                                                                                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
        }
        catch(PDOException $ex) {
            echo "An Error occured : ".$ex->getMessage();               
        }

    }

}