Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDO: Call to undefined method DB::query()

Tags:

php

mysql

pdo

Trying to get to hang of PDO but not having much fun at the moment. I bet it's something really simple as well.

EDIT: What would be a better way to go about doing this? i.e instead of wrapping it in a class?

classes/DB.class.php:

<?php

// DB.class.php

class DB {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    // Establish Connection to Database.

    public function connect() {

        try {
            $DB = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
        }
        catch (PDOException $e) {
            echo $e->getMessage();
        }

    }

}

?>

includes/global.inc.php:

<?php

require_once 'classes/DB.class.php';

// Establish Connection to Database.

$db = new DB();
$db->connect();

?>

index.php:

<?php

require_once 'includes/global.inc.php';

$STH = $db->query("SELECT * FROM users");
echo "<pre>";
print_r($STH->fetch());

?>
like image 230
ritch Avatar asked Jun 10 '11 14:06

ritch


4 Answers

You don't have DB property and query() method in your DB class. Add it like this listing:

class DB
    {
    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";
    protected $DB = null;

    // Establish Connection to Database.
    public function connect()
        {
        try
            {
            $this->DB = new PDO("mysql:host=".$this->db_host.";dbname=".$this->db_name."", $this->db_user, $this->db_pass);
            } 
        catch(PDOException $e)
            {
            echo $e->getMessage();
            }
        }

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

The better way would be to use some ORM library or bare PDO object - it's quite friendly.

like image 149
Tomasz Kowalczyk Avatar answered Oct 12 '22 14:10

Tomasz Kowalczyk


Try this:

class DB extends PDO {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    public function __construct() {
        try {
            parent::__construct("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

}

$db = new DB;
$db->query('SELECT * FROM something');

Also, I added the $this keyword in front of your members, because $db_name and such were not declared in the method scope.

If you do not want the connection to be initiated when the object is created, you could do:

class DB extends PDO {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    public function __construct() {
        // do nothing
    }

    public function connect() {
        try {
            parent::__construct("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }

}

$db = new DB;
$db->connect();
$db->query('SELECT * FROM something');

Important note: Normally, when overriding methods in children, you need to specify the same method signature as the parent (or you'll get an E_STRICT error). Fortunately, this doesn't apply to core classes, probably to allow overrides like this.

like image 35
netcoder Avatar answered Oct 12 '22 14:10

netcoder


The object instantiated as $db does not have the method query. There is probably not a need to wrap the PDO object within another object, but if you are going to do that, you need to make sure all methods are accessible.

like image 36
datasage Avatar answered Oct 12 '22 14:10

datasage


your class DB has no method query! you could do it this way:

<?php

    // DB.class.php

    class DB {

    protected $db_name = "PDO";
    protected $db_user = "root";
    protected $db_pass = "root";
    protected $db_host = "localhost";

    private $_db;

    // Establish Connection to Database.

    public function connect() {

        try {
            $this->_db = new PDO("mysql:host=".$this->db_host.";dbname=".$this->db_name, $this->db_user, $this->db_pass);
        }
        catch (PDOException $e) {
            echo $e->getMessage();
        }

    }

    public function __call($name, array $arguments) {

        if(method_exists($this->_db, $name)){
            try{
                return call_user_func_array(array(&$this->_db, $name), $arguments);
            }
            catch(Exception $e){
                throw new Exception('Database Error: "'.$name.'" does not exists');
            }
         }
     }

}

?>

With the magic function __call() you can pass all functions that PDO supports to your newly created PDO Object.

like image 28
Sascha Galley Avatar answered Oct 12 '22 12:10

Sascha Galley