izolate
izolate

Reputation: 1600

Failing to reference a PDO instance set in class __construct()

Within the class itself, I can't seem to reference the PDO instance set in the __construct() function.

Code

Class

class Category {

    protected static $pdo;

    private function __construct() {
        try {
            self::$pdo = new PDO('mysql:host=localhost;dbname=database', $username, $password);
            self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch (PDOexception $e) {
            return $e->getMessage();
        }
    }

    // convert category slug to id
    public static function slug_to_id($category_slug) {

        $query = self::$pdo->prepare('SELECT id FROM `category` WHERE slug = :slug');
        $query->execute(array('slug' => $category_slug));

        $data = $query->fetch(PDO::FETCH_ASSOC);
        return $data['id'];
    }
}

Call

$id = Category::slug_to_id($category_slug);
print_r($id);

Error

PHP Fatal error:  Call to a member function prepare() on a non-object

How can I make the __construct stuff work?

Upvotes: 2

Views: 86

Answers (1)

Havelock
Havelock

Reputation: 6968

The way you instantiate the PDO object is the problem. You do it in the constructor, which on success should return an instance of the class Category, but you never call the constructor, which you really don't need since you have all static methods.
One possibility, if you insist on working with static methods, would be to instantiate the PDO object in a e.g. init() method.
Something like

class Category {

    protected static $pdo = null;

    private function init() {
        try {
            self::$pdo = new PDO('mysql:host=localhost;dbname=database', $username, $password);
            self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch (PDOexception $e) {
            return $e->getMessage();
        }

        return true;
    }

    // convert category slug to id
    public static function slug_to_id($category_slug) {

        // check whether the object's been instantiated
        if (self::$pdo === null) {
            $res = self::init();
        }

        if (is_string($res)) { 
            // an exception has been thrown
            // do something with the message you've got in $res
        }

        $query = self::$pdo->prepare('SELECT id FROM `category` WHERE slug = :slug');
        $query->execute(array(':slug' => $category_slug));

        $data = $query->fetch(PDO::FETCH_ASSOC);
        return $data['id'];
    }
}

Also, please see the small but subtle change in the way of calling the execute method at the end.

Upvotes: 2

Related Questions