tags:

views:

90

answers:

2

The following two statements should be identical, yet the commented out statement does not work. Can anyone explain ?

$peer = GeneralToolkit::getPeerModel($model);
//return call_user_func(get_class($peer).'::retrieveByPK',array($comment->getItemId()));
return $peer->retrieveByPK($comment->getItemId());

PS: I am using PHP 5.2.11

+2  A: 
return call_user_func(
    array($peer,'retrieveByPK'),
    $comment->getItemId()
);

is the equivalent of

return $peer->retrieveByPK($comment->getItemId());

The first argument gives an object reference, and a function name. The second argument gives the arguments passed to the function that is being called.

The :: syntax is used to reference static methods and properties of a class. Which is different from referencing non-static methods and properties.

Peter Lindqvist
It is wrong. retrieveByPk is not a static function in the working example.
Matijs
Matjis is right, your code did not work, and the second solution you offered does not unfortunately, answer my original question.
Stick it to THE MAN
Right, i misunderstood the question a bit. Updated my answer to reflect this.
Peter Lindqvist
+2  A: 

The two calls are not the same. You are calling:

return GeneralToolkit::retrieveByPK(array($comment->getItemId());

So of course you get a different answer. This is the correct code:

return call_user_func(array($peer, 'retrieveByPK'), $comment->getItemId());

Unless 'retrieveByPK' is static but then you should use one of these calls (that all do the same thing):

return call_user_func(
    get_class($peer) . '::retrieveByPK', 
    $comment->getItemId());

return call_user_func(
    array(get_class($peer), 'retrieveByPK'), 
    $comment->getItemId());

return call_user_func_array(
    get_class($peer) . '::retrieveByPK', 
    array($comment->getItemId()));

return call_user_func_array(
    array(get_class($peer), 'retrieveByPK'), 
    array($comment->getItemId()));

So in that case your error was in using array() while calling call_user_func() instead of call_user_func_array().

Explanation added

Classes have two main types of functions static and non-static. In normal code non static functions are called using ClassName::functionName(). For non-static functions you need first to create an object using $objectInstance = new ClassName(), then call the function using $objectInstance->functionName().

When using callbacks you also make a distinction between static and non-static functions. Static functions are stored as either a string "ClassName::functionName" or an array containing two strings array("ClassName", "FunctionName"). A callback on a non static functions always is an array containing the object to call and the function name as a string: array($objectInstance, "functionName).

See the PHP Callback documentation for more details.

Matijs
Your code is correct (I tried it). I still dont understand however, how my commented out line is equivalent to the line you wrote. I thought get_class($peer) would return the name of the peer class, as a string, which would then be appended to the '::retrieveByPK' string, to complete the method name. Please explain why get_class($peer) returns 'GeneralToolkit' - or did you make a mistake?
Stick it to THE MAN
As it turns out, this also works: return call_user_func(array(get_class($peer), 'retrieveByPK'), $comment->getItemId());
Stick it to THE MAN
From your example we cannot be sure that get_class($peer) does return GeneralToolkit, but if you have symfony experience i guess it's possible to know that. If it's true, which is something i don't know.
Peter Lindqvist