PDA

View Full Version : OOP PHP Classes - Using Parent Variables


komodo
09-12-2007, 08:27 PM
I'm fairly new to PHP classes, but I've gotten myself into a situation where I have a solution that WILL work, but I feel like it's not the best way.

There are three classes involved here...

1) I have a Database class, which is a wrapper that connects to the database and holds a connection, waiting for new queries.

2) The next class is the main object. In the constructor of this class, I initialize a new Database object (above), establish the connection, and use it periodically. In this class I also have a second object initiated, described next.

3) This class object is a child of the main object (2). It needs periodic database access as well.

My question is, is there anyway for class 3 to call back to the parent's (2) database object, and access it's functions?

What I'm trying to avoid is a complete new instance of the database connection being made in class 3, when a perfectly good connection has already been established in the main object (2). It seems like a waste to have multiple connections to the same database from a single script.

Thanks. :)

GJay
09-12-2007, 08:52 PM
you can pass the Database instance to the child, either via the child's constructor, or via a specific setter:

class Database {

}

class Foo {

private $db;

private $bar;

public function __construct() {
$this->db = new Database();
$this->bar = new Bar();
$this->bar->setDB($this->db);
}
}
class Bar extends Foo {
public function __construct() {

}

public function setDB(Database $db) {
$this->db = $db;
}
}

Allowing your Foo classes to be sent a Database instance wouldn't be such a bad idea, would allow you to swap in different DB implementations very easily (and mock-objects for testing).

Is the Child class definitely worth of inheritance though? Does the phrase 'Bar is a Foo' make sense with your classes, or would 'has a' be more correct? Compositing an instance of a child class has a bit of a 'bad smell' to it, not necessarily wrong but probably worth getting a second opinion over.

PremiumBlend
09-12-2007, 09:01 PM
Is the Child class definitely worth of inheritance though?

This makes sense to me. You have a Database class that has a connection, and other properties. Then inherited classes could be a MySQL Database class or a PostGres DB class. Different implementations of a generic class. That's just my thoughts.

komodo
09-12-2007, 09:10 PM
Ah, the setDB function is a great idea...

Unfortunately, the way the objects are built, they're not extensions (doesn't make sense).

I was trying to do crazy things like $this->db = $parent->db when the parent's $db was public.... needless to say, that failed miserably, hah.

Does this seem to be the best way of approaching it?

komodo
09-12-2007, 09:13 PM
Wait, that doesn't accomplish what I'm trying to do at all, does it?

That saves me from reconfiguring the class, but it doesn't save memory or database connections... since the get function creates a separate copy of the Database object, right?

I'm more looking for a way to reference the parent's actual instance of that class, or create a pointer-style reference I can use locally.

Make sense?

GJay
09-12-2007, 10:55 PM
This makes sense to me. You have a Database class that has a connection, and other properties. Then inherited classes could be a MySQL Database class or a PostGres DB class. Different implementations of a generic class. That's just my thoughts.

That's not how I read the original post. There's no mention of the Database class being involved in the relationship, it's just used by both the parent and the child. Having actual examples rather than abstracted examples would of course have stopped this being an issue...

If you're using PHP5, then objects are passed by reference, there is no extra memory or connection. If you're not, and are serious about developing in an OO manner, then upgrade- PHP4 is dead.

komodo
09-12-2007, 11:33 PM
That's not how I read the original post. There's no mention of the Database class being involved in the relationship, it's just used by both the parent and the child. Having actual examples rather than abstracted examples would of course have stopped this being an issue...

If you're using PHP5, then objects are passed by reference, there is no extra memory or connection. If you're not, and are serious about developing in an OO manner, then upgrade- PHP4 is dead.

I am using PHP5.

So you're saying if I use that getDB function example above, it'll use a reference to the existing object, rather than creating an entirely new copy of the instance?

marek_mar
09-13-2007, 01:31 AM
That code is obscure. First of all, bar is (a type of) foo. Thereis no reason for bar be a member of foo. If PHP would call parent constructors you would get infinete recursion.

komodo
09-13-2007, 01:38 AM
That code is obscure. First of all, bar is (a type of) foo. Thereis no reason for bar be a member of foo. If PHP would call parent constructors you would get infinete recursion.
Not in this example.

Foo and bar are completely separate engines, both using the database object.

Except now, bar is an engine being called from inside the foo object, however the bar object might also be called by other objects later on.

GJay
09-13-2007, 07:25 AM
Can you not just give us the context (the class-names would probably be enough to decide)? At the very least do a search for "favour composition over inheritance" and see what other people have to say on the subject

aedrin
09-13-2007, 04:23 PM
Database object access works good in a singleton pattern.


class Something {
public function doSomethingElse() {
$db = Database::getInstance();
$db->query( /* ... */ );
}
}

komodo
09-13-2007, 05:58 PM
Database object access works good in a singleton pattern.


class Something {
public function doSomethingElse() {
$db = Database::getInstance();
$db->query( /* ... */ );
}
}

That's got me curious. Would you mind expanding on that a bit?

The getInstance() function I would have to write, correct? How would it retun?

And how would the public function play into this? Would it be in the parent class, called by the child?

Thanks.

aedrin
09-13-2007, 06:05 PM
You would call this whenever a method/function needed access to the database. Here's a basic writeup of the Database class (for more details, look up 'Singleton pattern')


class Database {
private static $_instance = null;

public static function getInstance() {
if (self::$_instance == null) {
// create the database object/connection
// this is where you can do some interesting stuff
// for instance, read a standard configuration file and build the connection off of that
// taking that further, the configuration file could specify which engine (mysql, postgresql, etc.) and you load the class dynamically based on that
}

return self::$_instance;
}
}


Note the use of the static (http://us2.php.net/manual/en/language.oop5.static.php) keyword.