Self Referencing References

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Self Referencing References

Post by Ambush Commander »

Code: Select all

function register($name, &$object) {
    $this->$name = &$object;
}
and

Code: Select all

$this->global->register('book',&$this);
Am I overdoing the ampersands? In what places are the ampersands needed?
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

It depends, what does the rest of your class looks like? is $this the name of your class? I don't think you can do that.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Well, let me rewrite it a bit.

Code: Select all

class TheBucket {
  var $water;
  function register($name, &$object) {
    $this->$name =& $object;
  }
}
 
class TheWater {
  var $reference_to_bucket;
  function TheWater() {
    global $BUCKET;
    $BUCKET->register('water',&$this);
    $this->reference_to_bucket =& $BUCKET;
  }
}
 
$BUCKET =& new TheBucket;
$water =& new TheWater;

var_dump($BUCKET);
Edit Err.. forgot to set the reference. Here's the output:

Code: Select all

object(thebucket)
  'water' => 
    object(thewater)
      'reference_to_bucket' => 
        object(thebucket)
          'water' => 
            object(thewater)
              'reference_to_bucket' => 
                object(thebucket)
                  'water' => 
                    object {
Edit Two And it's not any sort of tomfoolery either! It works in PHP 5:

Code: Select all

object(TheBucket)#4 (1) {
  ї&quote;water&quote;]=>
  object(TheWater)#5 (1) {
    ї&quote;reference_to_bucket&quote;]=>
    &object(TheBucket)#4 (1) {
      ї&quote;water&quote;]=>
      object(TheWater)#5 (1) {
        ї&quote;reference_to_bucket&quote;]=>
        *RECURSION*
      }
    }
  }
}
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

Why not use extends TheBucket in TheWater class?
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Because variables have to exist somewhere. Water is not a logical extension of a Bucket, rather, it resides within it (so thus the reference in the bucket). However, the water would like to be able to influence the bucket, so it needs a reference pointing to the bucket. It's how I'm letting objects access each other. You store references in a global variable, and then you assign convenient references to that global variable and then operate on it.
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

OK, I may be confused, but doesn't this do what you’re trying to do?

Code: Select all

class TheBucket {
  var $contents;
  function fillBucket( &$Obj ) {
    $this->$contents = &$Obj ;
  }
}
 
class TheWater {
  var $amount_of_h2o;

  function TheWater($amt) {
    $this->amount_of_h2o = $amt;
  }
}
 
$MyBucket = new TheBucket;
$SomeWater = new TheWater(150);

$MyBucket->fillBucket( &$SomeWater );
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Almost, but there's an extra element, and I think we should scratch the metaphor.

In order to understand why I'm doing this, you have to understand one principle I'm trying to enforce while I'm coding this class. Code for specific tables stays in its own class.

So, suppose I'm pulling information about comments members have made. Attached to the comment is the userid of the member, but what we want to display is the actual name of the member. That requires a query to a different table, so what we do is we squirrel away that MySQL into another class.

What happens when we want our comment class to be self sufficient and give us the names of the authors we want? We have it invoke the author class, have the author class query for the real name of the author, cache it (so if the same author comes up later in the same execution, there's no extra query) and pass it back to the comment class so it can incorporate it in it's variables.

There's no hierarchy, so we put 'em all in "TheBucket" and then give them references to the bucket so they can easily manipulate their peers.

So... the code you're suggesting covers the insertion of the objects into the bucket fairly well without messy references, but its a bit more, I guess.

You know, that does mean one thing though: if you move all the cross object tomfoolery inside the Bucket class and then execute the instructions from there, then you won't have to worry about the references, but it's just not possible to put all the code there.
Post Reply