2

Hey guys, so I'm completely new to Object Oriented PHP -- I've read some tutorials, but I can't find anything that really goes into working with a database with PHP classes.

I'm trying to make something simple -- a quick news post class. You get the post from the database, etc. However, I'm getting an error whenever I try to interact with the database.

I read that PDO is the way to go with OO PHP; to that end, I've developed a database class, as detailed in this post: Use of PDO in classes

class Database
{
    public $db;   // handle of the db connexion
    private static $dsn  = "mysql:host=localhost;dbname=test";
    private static $user = "admin";
    private static $pass = "root";
    private static $instance;

    public function __construct () 
    {
        $this->db = new PDO(self::$dsn,self::$user,self::$pass);
    }

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

    // others global functions
}

I then attempt to use it in my PHP class, in order to retrieve data on a news post:

<?php
require_once "database.php";

class news extends Database
{
    private $title;
    private $author;
    private $date;
    private $content;
    private $category;


    function __construct($id)
    {
        $db = Database::getInstance();
        $query = $this->db->prepare("SELECT title, author, date, content, category FROM news WHERE id = :id LIMIT 1");
        $query->bindParam(":id", $this->id, PDO::PARAM_INT);
        if ($query->execute())
        {
            $result = $query->fetch(PDO::FETCH_OBJ);

            $this->set_title($result->title);
            $this->set_author($result->author);
            $this->set_date($result->date);
            $this->set_content($result->content);
            $this->set_category($result->category);
        }
    }
<...>
?>

Every time I try to run this script though, I get the following error:

Fatal error: Call to a member function prepare() on a non-object in /news.class.php on line 16

Any ideas?

1
  • 3
    Side note: if you want to implement the Database class as a singleton (i.e. xx::getInstance()), leave __construct() blank or even make it private so that getInstance() is the only way to access it. Otherwise it's just a regular class with funny instantiation. Commented Jul 8, 2010 at 2:44

3 Answers 3

3
$db = Database::getInstance();
$query = $this->db->prepare();

You'll have to use either $db or $this->db both times. $db is a variable in the local function. $this->db is an instance variable of the class. They're not the same. In this case, $this->db does not exist and as such has no member function prepare, as the error states.

You're trying to create $this->db in your parent's constructor, but since you're overriding the constructor in the child class, that code is not run. You would need to call parent::__constructor for that code to run.

Sign up to request clarification or add additional context in comments.

2 Comments

Error has changed; Shouldn't prepare() exist though, since I have $db as a PDO object in the Database class? Fatal error: Call to undefined method Database::prepare() in /home1/centasmn/public_html/other_sites/test/news.class.php on line 16
Database::getInstance returns an instance of the Database class, which by itself doesn't have a prepare method either. $db->db is the object you're looking for, but that's probably not how you wanted to use the object.
3

Your design is flawed. Why does news extend Database? Database represents your global database connection. One single row of the news table is not a database connection. So it should not inherit from it. What you should do is follow the "favor composition over inheritance" principle.

Extending a singleton is not a good idea. As a matter of fact, singletons are a bad idea in general, because they make your code monolithic.

What you are doing is basically object-relational mapping. You should take a look at some existing PHP ORMs, I suggest Doctrine.

1 Comment

And what if I don't want to use something as big as Doctrine, how would you do Database/Objects interactions?
-1

$db = Database::getInstance(); need to be: $db = new Database();

And this line $query = $this->db->prepare(); need to be $query = $db->prepare();

Then this $query->bindParam(":id", $this->id, PDO::PARAM_INT); need to be $query->bindParam(":id", $id, PDO::PARAM_INT);

I'm not sure why you need the getInstance() function in the Database class? The

new Database()

will give you a new instance.

2 Comments

I believe he's aiming for a singleton pattern with getInstance.
Probably -- but I want to learn good habits right from the get go, even if it means a steeper learning curve. Thanks for the answer though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.