我自己的PHP类中的PDO

时间:2013-07-30 11:24:36

标签: php class pdo

我是PDO的新手。我看了好几个视频。我想像以前一样使用我自己的数据库类。我想使用PDO而不是mysql *函数。我知道在PHP 5.5中不推荐使用mysql *函数

我没有处理我的旧数据库类。因为对新手来说会更难。现在我只创建一个连接。我想选择我的产品。

这是我的代码:

class Database extends PDO {
    private $_server         = "localhost";
    private $_user           = "root";
    private $_password       = "";
    private $_db             = "demo";

    private $_engine = 'mysql';
    private $link = NULL;


    public function __construct() {
        $dsn = $this->_engine.':dbname='.$this->_db.';host='.$this->_server.';charset=utf8';

        try {
            $this->link = new PDO($dsn, $this->_user, $this->_password);
            $this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo 'Connection failed: ' . $e->getMessage();
        }
    }
}

header('Content-Type: text/html; charset=utf-8');
$DB = new Database();

$sql = "SELECT * FROM product";
$q  = $DB->query($sql);
while($r = $q->fetch(Database::FETCH_ASSOC)){
    $products[] = $r;
}

echo "<pre>";
print_r($products);
echo "</pre>";

我无法取得我的产品。我收到了错误。

  

警告:PDO :: query():SQLSTATE [00000]:无错误:未在/var/www/dt/includes/class/class.database.php中调用PDO构造函数   第52行

     

致命错误:在非对象中调用成员函数fetch()   第53行的/var/www/dt/includes/class/class.database.php

我的错误是什么?我该怎么办?

2 个答案:

答案 0 :(得分:3)

关于您的代码的一些随机想法。

滥用类继承

class Database extends PDO {
    private $link = NULL;

    public function __construct() {
            $this->link = new PDO($dsn, $this->_user, $this->_password);

Database实例本身将是一个PDO对象,因此将PDO对象放在另一个PDO对象中是没有任何意义的(其外部甚至无法正常工作,因为它没有没有初始化)。所有你需要的是:

class Database extends PDO {
    public function __construct() {
        parent::__construct($dsn, $this->_user, $this->_password);

未初始化的属性

public function __construct() {
    $dsn = $this->_engine.':dbname='.$this->_db.';host='.$this->_server.';charset=utf8';

所有$this->个变量来自何处?您可能希望将它们作为构造函数参数传递。

中断错误处理

try {
    $this->link = new PDO($dsn, $this->_user, $this->_password);
    $this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

您的类将连接错误降级为标准输出上的纯字符串。现在,无法记录或检测连接错误。

编辑:您询问如何检测或记录班级中的连接错误。你可以做很多事情,但最简单的方法就是做......没事。认真。如果您只是从构造函数中删除try / block,PDO异常将自动冒出,您将能够在任何需要的地方处理异常。 E.g:

try{
    $DB = new Database();
}catch(PDOException $e){
    // I want to handle connection errors in a special way
    // I'll log them here and I'll redirect the user to a static error page
    // That's something I couldn't do from the class constructor because I'd be missing context
}

......甚至:

try{
    $DB = new Database();
    $sql = "SELECT * FROM product";
    $q  = $DB->query($sql);
    while($r = $q->fetch(Database::FETCH_ASSOC)){
        $products[] = $r;
    }
}catch(Exception $e){
    // I prefer to handle all exceptions the same way, no matter the source
}

...但是我会选择第一种方法:连接错误是您可以在生产中找到的唯一PDOException个实例,而且您通常无法做任何事情,所以给它们是有意义的特殊待遇。

答案 1 :(得分:1)

首先将您的错误报告排序。如果要调试,您需要能够看到错误!

为此,您需要在php.ini

中修改以下设置

error_reporting display_errors

确保在php.ini文件中完成此操作(而不是在代码中使用ini_set()),然后重新启动服务器。

对于您的database abstraction,我看不到扩展PDO课程的任何实际好处。一般来说,如果有的话,我只会扩展课程 我想要重载的父级内的一些功能。

可能更有用的是encapsulate通过将PDO实例包装到您自己的自定义类中来调用它们。这里的主要好处是那里 没有直接处理PDO实例的客户端代码,您可以更改或交换类的实现,而不会影响 其余的代码。

一个人为的例子:

class Database
{
  protected $config = array();

  protected $pdo;

  public function __construct(array $config)
  {
    $this->config = $config;
  }

  protected function getPdo()
  {
    if (null == $this->pdo) {
      try {
        $config = $this->config;

        $dsn = $config['engine'].':dbname='.$config['database'].';host='.$config['host'].';charset=utf8';

        $this->pdo = new PDO($dsn, $config['user'], $config['password']);
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

      } catch (PDOException $e) {
        echo 'Connection failed: ' . $e->getMessage();
      }
    }
    return $this->pdo;
  }

  public function query($sql)
  {
    return $this->getPdo()->query($sql);
  }

}

$db = new Database(array(
  'engine' => 'mysql',
  'database' => 'databasename',
  'host' => 'localhost',
  'user' => 'fred',
  'password' => 'mypassword'
));
$results = $db->query('SELECT * FROM sometable');