Class interaction

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
jurriemcflurrie
Forum Commoner
Posts: 61
Joined: Wed Jul 06, 2005 7:14 am
Location: Den Haag, the Netherlands

Class interaction

Post by jurriemcflurrie »

Hey, I have a question wich is probably already questioned before, but I couldn't find it.

I can't figure out the best way to interact between classes. Let's say I have an error class and a db class, I want the db errors to be send to the error class.

I saw that I can do that with references, though I cant get it to work.

Another question is that I have another class called news, how can I include the db class in de news class the best way? Now, I do something like this:

Code: Select all

<?
class db {
	// DB methods
}

class news {
	var $db;
	
	function news() {
		$this->db = new db;
	}
}
?>
I hope I'm clear :)

thanks in advance!
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Interaction between classes is called message passing. For one object to pass a message to another, it has to be aware that it's there to take the message. Here is an example.

Code: Select all

class db
	{
	var $error;
	
	function db(&$error)
		{ $this->error=&$error; }
	
	function queryDB($SQL)
		{
		/* act as if query failed */
		$this->error->testError('The query failed!');
		return false;
		}
	}
	
	
class news
	{
	var $error;
	var $db;

	function news(&$db, &$error)
		{
		$this->db=&$db;
		$this->error=&$error;	
		}
	
	function getNews($top_subject, $from_date, $to_date)
		{
		if($this->db->queryDB($SQL)==false)
			{ $this->error->testError('News retrieval failed!'); }
		return false;
		}
	}
	
	
class error
	{
	
	function testError($err_str)
		{ echo "This output is from the error object!\n".$err_str."\n"; }
	
	}
	

# Instantiate objects
$err=new error;
$db=new db($err);
$news=new news($db, $err);

# Try to get the news
$news->getNews('weather', '1/2005', '3/2005');
Both the news and db objects have a handle to the same error object. How I did this is obvious, but take note of the fact in the constructor declerations that the objects are passed in by reference!

When you run this, you will actually see two messages. In other words, not only is the $news object sending a message to the error object, but the db object is as well. From one request, we were able to start a chain of events that was the message passing amongst multiple objects. As you can see, a message is initially passed from the $news object to the $db object.

Hope that helps,
Cheers
User avatar
jurriemcflurrie
Forum Commoner
Posts: 61
Joined: Wed Jul 06, 2005 7:14 am
Location: Den Haag, the Netherlands

Post by jurriemcflurrie »

Very clear!

thanks
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

Much more advanced, but I frequently use Registries get achieve the same effect, which is passing data around globally (without actually using globals). This avoids the need of having to pass around object soup to the individual classes.
Last edited by John Cartwright on Mon Dec 19, 2005 1:10 pm, edited 2 times in total.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Jcart wrote:Much more advanced, but I frequently use Registries get achieve the same effect, which is passing data around globally (without actually using globals). This avoids the need of having to pass around object soup to the individual classes.
I agree. I use the same thing. But that would've been over the top in this case.
User avatar
patrikG
DevNet Master
Posts: 4235
Joined: Thu Aug 15, 2002 5:53 am
Location: Sussex, UK

Post by patrikG »

A very pattern-oriented discussion of this is at http://www.phppatterns.com/docs/design/the_registry

I agree with BDKR that the registry would be over the top - unless it's for your own learning experience. Then, by all means, be as over-the-top as you want :)
User avatar
m3mn0n
PHP Evangelist
Posts: 3548
Joined: Tue Aug 13, 2002 3:35 pm
Location: Calgary, Canada

Post by m3mn0n »

Excellent link. I also recommend checking out the manual page for extends.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

patrikG wrote:A very pattern-oriented discussion of this is at http://www.phppatterns.com/docs/design/the_registry

I agree with BDKR that the registry would be over the top - unless it's for your own learning experience. Then, by all means, be as over-the-top as you want :)
LOL for some odd reason I linked the regex forum, when I meant to post that link :roll:

I've fixed my link to avoid the confusion.
User avatar
patrikG
DevNet Master
Posts: 4235
Joined: Thu Aug 15, 2002 5:53 am
Location: Sussex, UK

Post by patrikG »

:lol: nice one
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Jcart wrote:
patrikG wrote:A very pattern-oriented discussion of this is at http://www.phppatterns.com/docs/design/the_registry

I agree with BDKR that the registry would be over the top - unless it's for your own learning experience. Then, by all means, be as over-the-top as you want :)
LOL for some odd reason I linked the regex forum, when I meant to post that link :roll:

I've fixed my link to avoid the confusion.
Kinda confused me on that one. I was thinking "Oh great, what else don't I know?" LOL....
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Haven't read much into this.. but essentially a registry object is akin to the super globals? e.g.:

Code: Select all

<?php

$var = 0;

$RegistryObject->setValue('var', 0);

function someFunction () {
    global $RegistryObject;

    $newVar = $GLOBALS['var'];
    //or..
    $newVar = $RegistryObject->getValue('var');
}

?>
?
User avatar
jurriemcflurrie
Forum Commoner
Posts: 61
Joined: Wed Jul 06, 2005 7:14 am
Location: Den Haag, the Netherlands

Post by jurriemcflurrie »

Ok, i've read the article about registry. Don't get it just yet but with some practice i will.

I don't think extends is for me, couse I don't want db methods in my news or error class directly....

Maybe you all should have a look at the project I'm working on, and where all my questions are about. It's my computer to work with so don't expect speed... here's the link
http://212.238.148.197/

It's gonna be the intranet of my work... Login with test / test. It's in dutch but I think you get the point of the whole thing :)

So.. is it 'over the top' to use registries in this case? I personally don't think so and I will see how I can implement it...


One other thing
I hate to ask questions couse i think i learn most when i figure out things myself. But i always end up here asking a question and get advanced answers.
Isn't there a site with advanced tutorials? Like more of these kind of problems?
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Haven't read much into this.. but essentially a registry object is akin to the super globals?
Its a fair comparison - but its not GLOBALS. The registry still has an advantage of being an object. Its like a variant on the GLOBALS scene but outside the global variable scope. It pretty useful in some places but I keep it to a minimum if there's another valid alternative.
User avatar
jurriemcflurrie
Forum Commoner
Posts: 61
Joined: Wed Jul 06, 2005 7:14 am
Location: Den Haag, the Netherlands

Post by jurriemcflurrie »

Well no reactions but i have another question :)

I get the point of those registries, but how do I use it? Like this?

Code: Select all

<?
include('modules/_register.php');
$reg = new register();
include('modules/_db.php');
$reg->set_entry('db', new db);

$db = $reg->get_entry('db');
$db->connect('localhost','root','pass','db');
?>
Couse I don't see an advantage then... if i still have to assign the classes to vars.

Or am I missing something?

thanks
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

In other words, you're operating under the assumption that you must first populate the registry with the classes you would need before using them? Is my understanding of what you're saying here correct?

If that's the case, I agree. :wink:

My opinion of what's ideal in some situations is a registry/factory type object. When you need an object of a particular type, you tell the factory to provide it for you. The factory allready knows the particulars of the objects it provides so you don't need to populate it up front.

Cheers,
BDKR
Post Reply