0

所以,我正在做一个需要数据库连接的项目。我选择使用 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

4

2 回答 2

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
于 2013-06-28T04:22:08.040 回答
-1

如果您想使用普通对象而不是 sigleton,请尝试以下操作:

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();               
        }

    }

}
于 2013-06-28T04:14:24.397 回答