Parent -> Child/parent -> Child. Child needs property from Parent

I’m still working on learning classes and I have a question regarding accessing an object property from an object instantiated inside another object.

Here is some sample code I’m playing with. It is in Class3 that I’m wanting to use the property from Class1.

<?php

  Class Class1
  {
    public $public;

    public function __construct($var)
    {
      $this->public = $var;

      include('class.class2.php');
      $Class2 = new Class2();

      return;
    }
  }

?>
<?php

  Class Class2
  {
    public function __construct()
    {
      include('class.class3.php');
      $Class3 = new Class3();

      return;
    }
  }

?>
<?php

  Class Class3
  {

    public function __construct()
    {
      print Class1::$public;

      return;
    }
  }

?>

Classes go from general down to specific objects. If there is a better way of doing this, please let me know. Thanks!

Read this, try the examples and come back here with your questions. Also, don’t use include to call up a class file - use require_once().

Note - I’m not trying to be curt and rude, but your question is so basic I suspect you’re trying to get the forum to do your homework (wouldn’t be the first time someone has done this).

Hi PHP John,

One way to do this that is clear what objects you are using is to pass an object into another object that need to use it. For example:


Class User {
  protected $o_Session;
  protected $name

  public function __construct(Session $session){
    $this->o_Session = $session;
  }
  public function getStoredName(){
    return $this->getName();
  }
  public storeName($name){
    return $this->setName($name);
  }
  protected function getName(){
   return $o_Session->get('name');
  }
  protected function setName($name){
    if($o_Session->set($name){
      return 1;
    } else {
      return 0;
    }
  }
}

$o_Session = new Session();
$o_User = new User($o_Session);
$name = null;
$name = 'John';
$o_User->storeName($name);
echo $o_User->getStoredName();

Obviously you need to sanitize the input values but you see how this works.

Steve

FYI What you’re trying to do goes against the Law of Demeter, which states that it is a good idea to only talk to classes one level up or down, but not any further (or, as it’s also often stated “only talk to your immediate friends, not to strangers” – a law to encourage loose coupling.

Maybe you could be more clear what you’re trying to do so we can help you further? This abstract problem doesn’t give much to go on.

Michael Morris, I understand. And I may be going about this the wrong way.

ScallioXTX, Let me see if I can explain it another way.

Let’s say that I have a class that describes a surgeon. one that describes a gallery, and one that describes a particular set of photos.

Each one of these classes can be, and are used independently from each other. Also, they can be subsets in this manner, Surgeon -> Gallery (built based on who the surgeon is) -> Photosets (built based on the surgical procedure).

In the Photosets, if there is no caption, there is a default used of the procedure name and the surgeon’s name (a property of the Surgeon class). I was looking for a way of accessing that property without having to pass that value down through the “nested” objects.

However, if there is a better way, or passing it down is the more correct way of doing it, I am asking the question.

Does that help?

In that case I would let the Photoset ask the Gallery for a default caption, which then in turn can ask the Surgeon for it’s name. That way the Photoset only talks to Gallery, and Gallery only talks to Surgeon, and Photoset never talks to Surgeon directly, thus you are not breaking Demeter’s Law.

Does that make sense, or did I not understand your question correctly?

ScallioXTX, thank you. I’ll look into it.

Seems to me that the photosets should have a reference to the procedure, and the procedure should have a reference to the surgeon.

Here’s how I might define the class relationship.

class Procedure
{
    // the name of this procedure
    private $name;
    
    // the surgeon who performed this procedure
    private $surgeon;
    
    // the photoset, or perhaps an array of photosets?
    private $photoset;
}

class Surgeon
{
    // the name of this surgeon
    private $name;
    
    // an array of procedures this surgeon has performed
    private $procedures;
}

class Photoset
{
    // the procedure this photoset depicts
    private $procedure;
    
    // this photoset's caption
    private $caption;
}

The relationships shown here probably closely match your database relations. Each procedure has one surgeon, and each surgeon may have many procedures. Each procedure can have many photosets, and each photoset belongs to just one procedure.

After you write the getters and setters, here’s how you could then write the photoset’s getCaption method.

public function getCaption()
{
    if (isset($this->caption)) {
        return $this->caption;
    } else {
        return $this->getDefaultCaption();
    }
}

public function getDefaultCaption() {
    return $this->getProcedure()->getName() . ', performed by ' . $this->getProcedure()->getSurgeon()->getName();
}