Home » Php » oop – PHP Classes: get access to the calling instance from the called method

oop – PHP Classes: get access to the calling instance from the called method

Posted by: admin July 12, 2020 Leave a comment

Questions:

sorry for that weird subject but I don’t know how to express it in an other way.

I’m trying to access a method from a calling class. Like in this example:

class normalClass {
     public function someMethod() { 
          [...]
          //this method shall access the doSomething method from superClass
     }
}

class superClass {
     public function __construct() {
          $inst = new normalClass;
          $inst->someMethod();
     }
     public function doSomething() {
          //this method shall be be accessed by domeMethod form normalClass
    }
}

Both classes are not related by inheritance and I don’t want to set the function to static.

Is there any way to achieve that?

Thanks for your help!

How to&Answers:

You can pass a reference to the first object like this:

class normalClass {
    protected $superObject;
    public function __construct(superClass $obj) {
        $this->superObject = $obj;
    }

    public function someMethod() { 
        //this method shall access the doSomething method from superClass
        $this->superObject->doSomething();  
    }
}

class superClass {
    public function __construct() {
          //provide normalClass with a reference to ourself
          $inst = new normalClass($this);
          $inst->someMethod();
    }
    public function doSomething() {
          //this method shall be be accessed by domeMethod form normalClass
    }
}

Answer:

You could use debug_backtrace() for this. It is a bit iffy but for debugging purposes it is usefull.

class normalClass {
 public function someMethod() { 
      $trace = debug_backtrace();
      $trace[1]->object->doSomething();
 }

}

Answer:

You have a few options. You can use aggregation like so

class normalClass
{
  protected $superClass;

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

  public function someMethod()
  {
    $this->superClass->doSomething();
  }
}

class superClass
{
  public function __construct()
  {
    $inst = new normalClass( $this );
    $inst->someMethod();
  }

  public function doSomething()
  {  //this method shall be be accessed by domeMethod form normalClass
  }
}

Or just a straight-up setter

class normalClass
{
  protected $superClass;

  public function setSuperClass( superClass $superClass )
  {
    $this->superClass = $superClass;
  }

  public function someMethod()
  {
    if ( !isset( $this->superClass ) )
    {
      throw new Exception( 'you must set a superclass' );
    }
    $this->superClass->doSomething();
  }
}

class superClass
{
  public function __construct()
  {
    $inst = new normalClass();
    $inst->setSuperClass( $this );
    $inst->someMethod();
  }

  public function doSomething()
  {  //this method shall be be accessed by domeMethod form normalClass
  }
}

Answer:

Depending on your use case, you might want to pass the instance to the function only:

class normalClass {
    public function someMethod($object) { 
        $object->doSomething();
    }
}

If normalClass::someMethod() can be called by multiple, distinct $objects, this might be the better choice (instead of providing the $object to the whole normalClass instance).

But regardless of that you might consider creating an Interface to use for type hinting:

interface ISomethingDoer {
    public function doSomething();
}

class normalClass {
    public function someMethod(ISomethingDoer $object) {
        # Now PHP will generate an error if an $object is passed
        # to this function which does not implement the above interface.
        // ...

class superClass implements ISomethingDoer {
    // ...

Answer:

woah I had the same problem than you but instead of going with the so simple pass the reference to the object, I went with an event manager, Basically, when something would happen in the normal class, it would trigger an event which was listened by a class and that said class(the listener) would call the super class to execute that functionality and if necessary pass it new arguments.

Anyways, whether you pass it as a parameter to your object or you go with an event based approach, both solutions work. Choose the one you prefers.

For more information on events, sympony explains it quite good.
http://symfony.com/doc/current/components/event_dispatcher/introduction.html