tags:

views:

60

answers:

3

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: http://stackoverflow.com/questions/2047264/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?

+2  A: 
$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.

deceze
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
Ian
`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.
deceze
That seems to have worked, thanks!
Ian
A: 

$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.

Y.J.
I believe he's aiming for a singleton pattern with `getInstance`.
deceze
Yes, but it would be good to walk before you run!
Y.J.
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!
Ian
+2  A: 

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, and because of this, 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.

igorw