0

I started using PHP classes and looked into OOP.

I played around by creating a Database class that looks something like this (snippet):

class Database
{

private $link;
private $result;
private $count;

    function connect()
    {
        $this->link = mysql_connect(DB_HOST, DB_USER, DB_PW);
        $return = $this->link ? 'Connected to database.' : 'Failed to connect.';
        $this->open(); // I have another function in this class to select the db
        echo $return;
    }

    function query($query)
    {
        $this->result = mysql_query($query);

    }

    function fetch()
    {
        return mysql_fetch_assoc($this->result);

    }

    function count()
    {
        $this->count = mysql_num_rows($this->result);
        return $this->count;
    }
}

Just to test, I created another class called Guestbook that looks like this:

class Guestbook
{

    function fetch()
    {
        Database::query('SELECT * FROM guestbook LIMIT 2');
        while($row = Database::fetch()){
        $result_array[] = $row;

        return $result_array;
    }   

}

Now I tested calling the functions:

$db = new Database();
$db->connect();
$db->query('SELECT * FROM test');
while($row = $db->fetch()) {
    echo $row['id'].'<br />';
}
echo $db->count();
$db->close();

This works as expected. So I went on with the Guestbook class:

$db->connect();
$guestbook = new Guestbook();
$results = $guestbook->fetch();

foreach($results as $gb) {  
    echo $gb['id'];
}

echo $db->count(); // HERE'S MY PROBLEM !

$db->close();

Everything works as I wanted, but the second time I call $db->count() it echos the previous count and not 2 (as I set LIMIT 2 in the Guestbook fetch function).

How do I interact with these classes properly, so I can use something like $db->count() globally?

Thanks in advance for any hints or solutions!

5
  • Why are you calling database statically from your Guestbook classed? If you want to use it statically you should declare it so, and only use it like that :) I recommend making database singleton. Commented Mar 2, 2012 at 14:17
  • 1
    The problem is the mixing of static and object calls here. Normalize it so you either use static or object everywhere. A suggestion is to look at the Singleton pattern. Commented Mar 2, 2012 at 14:25
  • 1
    Another thing is that you would usually keep all the fetching inside of the Guestbook class. You would call $guestbook->getPosts(), which in turn gets the data desired via a private or protected getDataRow() method that sets the data into a protected variable in Guestbook so you could access it as many times as you'd want without having to access the database every single time. Commented Mar 2, 2012 at 14:29
  • @BobKruithof Thank you very much for your tips. I'll defenitely look into that! Commented Mar 2, 2012 at 14:36
  • @MickHansen I'll look at Singleton pattern as well. Thank you! Commented Mar 2, 2012 at 14:36

5 Answers 5

4

First off, there is no reason to wrap mysql_* implementations in OOP. IF you are going to do OOP then just use Mysqli or PDO which have OOP classes you can extend.

Secondly you want to hold an instance of the Database in the GuestBook class, not make it an extension of the Database class itself.

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

4 Comments

I'm just playing around with the topic. I want to understand it, so I created something on my own. This is not going to be used in any real project.
I understand that, im just saying youre using a poor path to try and gain that understanding :-)
@Fabian real project or not, prodigalson gave you really useful indications on how to improve
@DamienPirsy that's why I gave +1 ;)
2

It is hard to give you a definitive advice on how you could wrap your database accessor with OOP and still access the count() globally.

Clearly your code is wrong.

by using the notation

Database::query

you are referring to some kind of static methods on the Database class which does not seem to be the intent here. It looks like your code does not crash because of some backward compatibility with PHP4.

you could rewrite Guestbook along this way :

class Guestbook
{

    private $db;

    function __construct(&$db) {
        $this->db = $db;
    }

    function fetch($option)
    {
        $this->db->query('SELECT * FROM guestbook LIMIT 2');
        while($row = $this->db->fetch()){
        $result_array[] = $row;

        return $result_array;
    }   

}

and then

$db = new Database();
$db->connect();
$guestbook = new Guestbook($db);
$results = $guestbook->fetch();
echo $db->count();

This technique uses a pattern known as "Dependency Injection"

Comments

1

Why would you use count from the db class when you have the results from the guestbook->fetch() method?

This does exactly the same trick:

echo count( $resutls );

1 Comment

There is no reason to do that in this case, imho. But if you really want it you could return the entire db object from Guestbook. It's not what you'd usually do because you just create unnecessary code for something that does already exist.
0

see the $db is a object of the class Database never access the function OR property of the Guestbook

you can get this directly with count( $resutls )

OR may have to go with the inheritance concept

Thanks

Comments

0

You mixing static with instantiated versions of your class. If you want to be able to create multiple instances of a class, you should have a __construct function. While it's not required, it's best practice to have one.

You are creating a new instance and assigning it to the $db variable ($db = new Database();). But then in your GuestBook class you are referencing the database class statically (Database::). That syntax references the "base" class which is the same across all instances. What you want to do is reference the instance of the database class you created. Typically you would pass the database instance to use into the GuestBook class in the constructor, store that in a class variable, then reference it using $this.

class Guestbook
private $db = null;
{
    function __construct($db) {
        $this->db = $db;
    }

    function fetch($option) {
        $this->db->query('SELECT ...');
        ...
    }
}

$db = new Database();
$guestbook = new Guestbook($db);

Comments

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.