Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/250.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我自己的PHP类中的PDO_Php_Class_Pdo - Fatal编程技术网

我自己的PHP类中的PDO

我自己的PHP类中的PDO,php,class,pdo,Php,Class,Pdo,我是PDO的新手。我看了几段视频。我想像以前一样使用我自己的数据库类。我想使用PDO而不是mysql*函数。我知道PHP 5.5中不推荐使用mysql*函数 我不在处理我的旧数据库类。因为这对新手来说会更难。现在我只创建一个连接。我想选择我的产品 这是我的密码: class Database extends PDO { private $_server = "localhost"; private $_user = "root"; pr

我是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{
private$\u server=“localhost”;
私有$\u user=“root”;
私有$_密码=”;
私有$_db=“demo”;
私有$_引擎='mysql';
private$link=NULL;
公共函数构造(){
$dsn=$this->_engine'.:dbname='.$this->_db'.;host='.$this->_server'.;charset=utf8';
试一试{
$this->link=新PDO($dsn,$this->\u用户,$this->\u密码);
$this->link->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_异常);
}捕获(PDO$e){
回显“连接失败:”。$e->getMessage();
}
}
}
标题('Content-Type:text/html;charset=utf-8');
$DB=新数据库();
$sql=“从产品中选择*”;
$q=$DB->query($sql);
而($r=$q->fetch(数据库::fetch_ASSOC)){
$products[]=$r;
}
回声“;
印刷品(产品);
回声“;
我拿不到我的产品。我收到了一些错误

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

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


我犯了什么错?我该怎么办呢?

一些关于代码的随机想法

类继承的滥用
数据库
实例本身将是一个
PDO
对象,因此在另一个PDO对象中包含一个PDO对象没有任何意义(该对象的外部甚至无法正常工作,因为它尚未初始化)。您所需要的就是:

public function __construct() {
    $dsn = $this->_engine.':dbname='.$this->_db.';host='.$this->_server.';charset=utf8';
未初始化属性 所有这些
$this->
变量从何而来?您可能希望将它们作为构造函数参数传递

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

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

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
}
。。。甚至:

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');

。。。但我会选择第一种方法:连接错误是在生产环境中可以找到的唯一的
PDOException
实例,而且通常对此无能为力,所以对它们进行特殊处理是有意义的。

关于代码的一些随机想法

类继承的滥用
数据库
实例本身将是一个
PDO
对象,因此在另一个PDO对象中包含一个PDO对象没有任何意义(该对象的外部甚至无法正常工作,因为它尚未初始化)。您所需要的就是:

public function __construct() {
    $dsn = $this->_engine.':dbname='.$this->_db.';host='.$this->_server.';charset=utf8';
未初始化属性 所有这些
$this->
变量从何而来?您可能希望将它们作为构造函数参数传递

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

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

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
}
。。。甚至:

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');

。。。但是我会选择第一种方法:连接错误是您在生产中可以找到的唯一的
PDOException
实例,并且您通常对此无能为力,因此对它们进行特殊处理是有意义的。

首先整理错误报告。如果要调试,您需要能够看到错误

为此,您需要在
php.ini

错误报告
显示错误

确保这是在
php.ini
文件中完成的(而不是在代码中使用
ini\u set()
),然后重新启动服务器

关于
数据库抽象
,我看不到扩展
PDO
类的任何真正好处。一般来说,我只会在有条件的情况下扩展类 我想重载父级中的某些功能

更有用的方法是将
PDO
实例的所有调用封装在自己的自定义类中。这里的主要好处是 没有直接处理PDO实例的客户机代码,您可以更改或交换类的实现,而不影响 代码的其余部分

一个人为的例子:


首先对错误报告进行排序。如果要调试,您需要能够看到错误

为此,您需要在
php.ini

错误报告
显示错误

确保这是在
php.ini
文件中完成的(而不是在代码中使用
ini\u set()
),然后重新启动服务器

关于
数据库抽象
,我看不到扩展
PDO
类的任何真正好处。一般来说,我只会在有条件的情况下扩展类 我想重载父级中的某些功能

更有用的可能是
封装
p的所有调用
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');