Callback from parent to child class

I cannot find a way to make a callback from a parent to child class work. This is my best try but the line ‘$callback = $this->_callback();’ executes the function immediately and the argument passed to the parent constructor is empty.

<?php
class General
{
	public function __construct($callback)
	{
		$callback(); // or call_user_func($callback);
		// general code
	}
}	

class Special extends General
{
	private function _callback()
	{
		// specialised code
	}
	
	public function __construct()
	{
		$callback = $this->_callback();
		parent::__construct($callback);
		// other specialised code
	}	
}

Any help is appreciated.

thanks all for your educational answers and acid24ro, your question is very much to the point:

I extended a zend component but ended up with many similar children. So I took the specialised code out and put in the grandchildren. I was left with one child which could not be used directly. So after some googling I found out that what I needed to do was to make the one child an abstract (extended) class and add callback as a protected abstract method, to be defined in the grandchildren.

Reason why I needed the callback in the first place was that the sql for my dbase was specialised but the db adapter was general and the output was needed for some specialised tasks, so going back and forth between child and parent.

My current solution, which works:

<?php
abstract class General
{
	public function __construct($options)
	{
	    //general code A needed in B
		$this->_callback();
		// general code 
	}
	
	abstract protected function _callback();
}	

class Special extends General
{
	public function __construct()
	{
		// specialised 
		parent::__construct($options);
		
	}
	
    protected function _callback();
    	{
    		// specialised code B dependent on A
    	}
}

:x thanks! :slight_smile:

There, fixed that for you.

</ocd> :stuck_out_tongue:

Nope, protected.

With protected methods, any class of the same base type can call it, even if it is an external call. Try this:


class Foo {
	protected function bar() {
		echo 'working';	
	}
	
	public function addFoo(Foo $foo) {
		$foo->bar();
	}
}


$foo1 = new Foo;
$foo2 = new Foo;
$foo1->addFoo($foo2); //will call bar() on $foo2

$foo2->bar(); //will fail

Protected also works.

Public: any class can call the function method
Protected: any child class can call the function method

I think you meant make the callback method public. Right?

Great insight, this was what I thought, you saved me the typing. :slight_smile:

PHP doesn’t support function pointers in that way.

You can declare anonymous functions and store them in a variable but there’s no way to get a reference to an existing function.

Using call_user_func as you stated, should work. The problem you have is that it’s private. Use what acid24ro provided but make the callback method protected and it should work:



<?php
class General
{
    public function __construct($callback)
    {
        call_user_func($callback);
        // general code
    }
}    

class Special extends General
{
    protected function _callback()
    {
        // specialised code
    }
    
    public function __construct()
    {
        $callback = array( $this, '_callback' );
        parent::__construct($callback);
        // other specialised code
    }    
}

It looks like you maybe over complicating things…


<?php
error_reporting(-1);
ini_set('display_errors', true);

class ParentObject
{
  public function __construct(){
    $this->callback();
  }
  
  protected function callback(){
    echo 'Parent';
  }
}

class ChildObject extends ParentObject
{
  protected function callback(){
    echo 'Child';
  }
}

new ParentObject(); #Parent
new ChildObject();  #Child

?>

Perhaps you meant to do this:

<?php
class General
{
    public function __construct($callback)
    {
        $callback(); // or call_user_func($callback);
        // general code
    }
}    

class Special extends General
{
    private function _callback()
    {
        // specialised code
    }
    
    public function __construct()
    {
        $callback = array( $this, '_callback' );
        parent::__construct($callback);
        // other specialised code
    }    
}

I don’t know if it will work though with _callback method being private.

Maybe you should let us know what problem are you trying to solve with that code.