Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/278.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_Namespaces - Fatal编程技术网

Php 未定义的方法,在类外使用PDO

Php 未定义的方法,在类外使用PDO,php,class,pdo,namespaces,Php,Class,Pdo,Namespaces,尝试在连接类之外运行查询时,我遇到以下错误 致命错误:调用 我有以下文件 Database.php namespace Core; use \PDO; class Database { private $pdo; private static $instance; private function __construct() { try { $this->pdo = new PDO("mysql:host=loc

尝试在连接类之外运行查询时,我遇到以下错误

致命错误:调用

我有以下文件

Database.php

namespace Core;

use \PDO;

class Database
{
    private $pdo;
    private static $instance;

    private function __construct()
    {
        try {
            $this->pdo = new PDO("mysql:host=localhost;dbname=db;", "root", "pw");
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (\PDOException $e) {
            echo $e->getMessage();
        }
    }

    public static function getInstance()
    {
        if (!isset(self::$instance))
            self::$instance = new Database();
        return self::$instance;
    }
}
namespace Auth;

use Core\Database;

class Auth
{
    protected $dbh;

    public function __construct()
    {
        $this->dbh = Database::getInstance();
        $query = $this->dbh->query("SELECT * FROM table");
    }
}
Auth.php

namespace Core;

use \PDO;

class Database
{
    private $pdo;
    private static $instance;

    private function __construct()
    {
        try {
            $this->pdo = new PDO("mysql:host=localhost;dbname=db;", "root", "pw");
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (\PDOException $e) {
            echo $e->getMessage();
        }
    }

    public static function getInstance()
    {
        if (!isset(self::$instance))
            self::$instance = new Database();
        return self::$instance;
    }
}
namespace Auth;

use Core\Database;

class Auth
{
    protected $dbh;

    public function __construct()
    {
        $this->dbh = Database::getInstance();
        $query = $this->dbh->query("SELECT * FROM table");
    }
}

提前感谢您的帮助。

您正在设置数据库类的属性并返回静态值。或许您可能希望这样做:

class Database extends \PDO{
  public static function getInstance(){
    if(!self::$instance){
      self::$instance = new self();
    }
    return self::$instance;
  }

  public function __construct(){
    try {
        parent::__construct("mysql:host=localhost;dbname=db;", "root", "pw", [
          \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
        ]);

        self::$instance = $this;
    } catch (\PDOException $e) {
        echo $e->getMessage();
    }
  }
}
就我个人而言,我这样做了,而不是创建一个愚蠢的包装类。

否则,您将不得不设置静态变量:

self::$instance = new PDO("mysql:host=localhost;dbname=db;", "root", "pw");

Auth
类中,您刚刚使用
Singleton
模式创建了
Database
类的实例,并尝试从类中未定义的
数据库
实例调用
query
方法。如果希望像
$this->dbh->query()
那样访问它,则需要构造
数据库
类的实例,同时返回
PDO
实例。像这个:

public static function getInstance() {
    if (!isset(self::$instance))
        self::$instance = new Database();
    return self::$instance->pdo;
}
我刚才在这里修改的是
返回self::$instance->pdo
。如果第一次调用
getInstance
,则在实例化
数据库
类后,它将返回
PDO
的对象,否则它只返回创建的
PDO
实例。现在可以在
Auth
类中执行
$this->dbh->query()

注意,只有当您不打算在
数据库
类中定义除
静态
方法以外的任何其他方法时,才需要这样做,如
getInstance
。因为
getInstance
的结果只允许您访问
PDO
属性和方法。因此,解决方案是在
Database
中定义一个
public
方法,该方法分别返回
PDO
实例

public static function getInstance() {
    if (!isset(self::$instance))
        self::$instance = new Database();
    return self::$instance;
}

public function getPDO() {
    return $this->pdo;
}
完成后,您可以访问
Auth
类中的
PDO
,如下所示:

public function __construct()
{
    $this->dbh = Database::getInstance()->getPDO();
    $query = $this->dbh->query("SELECT * FROM table");
}

希望有帮助

正如错误所说,您的数据库类中没有查询方法。getInstance()返回数据库类的一个实例,而不是PDO。@Devon,ok:我在Auth.php中将
$this->dbh->query
更改为
$this->dbh->PDO->query
,但还有其他方法吗?看起来有点乱。另外,将实例变量
$pdo
公开,否则您将无法在类外访问它,特别是当您从
Auth
类调用
->query(…)
时。单例DB对象是一种代码味道。通常构造一个PDO对象,并通过Auth对象的构造函数传递它。您是否用给出的任何答案解决了问题?如果一个有用,请投票,如果它解决了,请标记它。