简体   繁体   中英

Call to undefined method PHP PDO

I am getting an error

Call to undefined method Connection::prepare()

The error originates on the select4 method of QueryBuilder class(below). The first line where the prepare method is called.

Ideally Connection class should return the PDO object to QueryBuilder. It seems like i passed Connection object instance into the QueryBuilder.

Output from var_dump of private $pdo

object(QueryBuilder)#4 (1) { 
["pdo":"QueryBuilder":private]=> object(Connection)#2 (0) { } }
object(Connection)#2 (0) { }  

Explanation of code

I have a config class(not included) which accepts a json file (mysql connection info) and returns an array.

Its then passed into the Connection class to returns a new PDO object

class Connection {

  public function __construct($db) {

    $dsn = $db['dbs'] . ':host=' . $db['host'] . ';dbname=' . $db['dbName'];

    return new PDO($dsn, $db['user'], $db['pwd']);

  }
}

The QueryBuilder class accepts the PDO instance and stores it on the private variable.

class QueryBuilder {

 private $pdo;

 public function __construct($pdo) {

   $this->pdo = $pdo;

 }

 public function select4($sql) {

   $statement = $this->pdo->prepare(":sql :n");

   $statement->bindValue(n, 4, PDO::PARAM_INT);

   $statement->execute(['sql' => $sql]);

   return $statement->fetch(PDO::FETCH_CLASS);

 }

}

Call new instance of Connection passing array values from Config class

$pdo = new Connection(Config::getInstance()->get("db"));

Call new instance of QueryBuilder passing PDO instance from Connection

$query = new QueryBuilder($pdo);

$sql_1 = 'SELECT title, synopsis FROM blog LIMIT';
$blog = $query->select4($sql_1); // triggers error 

Update:

Thanks for the comments and help. I changed the Connection class to implement a public static variable $pdo. I used the constructor to assign the PDO object to the static variable.

class Connection {

  public static $pdo;    // Added a static $pdo

  public function __construct($db) {

    $dsn = $db['dbs'] . ':host=' . $db['host'] . ';dbname=' . $db['dbName'];

    self::$pdo = new PDO($dsn, $db['user'], $db['pwd']);    // assign PDO

  }

}

$pdo = new Connection(Config::getInstance()->get("db"));

$query = new QueryBuilder(Connection::$pdo);

Corrected a few minor mistakes in the select4 method and its working now. :)

Ideally Connection class should return the PDO object to QueryBuilder. It seems like i passed Connection object instance into the QueryBuilder.

You cannot achive that with constructor, returning a different object in constructor will not affect what is returned with new statement. See: Constructor returning value? .

You may try one of these approaches:

Inheritance

class Connection extends PDO {

  public function __construct($db) {

    $dsn = $db['dbs'] . ':host=' . $db['host'] . ';dbname=' . $db['dbName'];

    parent::__construct($dsn, $db['user'], $db['pwd']);
  }
}

use:

// Get Connection object which extends PDO class
$pdo = new Connection(Config::getInstance()->get("db"));

Static method

class Connection {

  public static function getPDO($db) {

    $dsn = $db['dbs'] . ':host=' . $db['host'] . ';dbname=' . $db['dbName'];

    return new PDO($dsn, $db['user'], $db['pwd']);
  }
}

use:

// Get PDO object using Connection static method
$pdo = Connection::getPDO(Config::getInstance()->get("db"));

Getter method

class Connection {

  /** @var PDO */
  private $pdo;

  public function __construct($db) {

    $dsn = $db['dbs'] . ':host=' . $db['host'] . ';dbname=' . $db['dbName'];

    $this->pdo = new PDO($dsn, $db['user'], $db['pwd']);
  }

  /**
   * Get PDO instance
   * @return PDO
   */
  public function getPDO() {
    return $this->pdo;
  }
}

use:

// Get PDO object using Connection object
$pdo = (new Connection(Config::getInstance()->get("db")))->getPDO();

You should definetely take a look at some mysql wrappers, like Laravel's database wrapper: https://github.com/illuminate/database . It is generally better to use checked solutions than reinvent the wheel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM