Calling static method of class by name
This is somewhat the second part to this question.
In my project, I have the following interface:
interface ISoapInterface {
public static function registerSoapTypes( wsdl &$wsdl );
public static function registerSoapOperations( NuSoapServer &$server );
public static function registerFaultHandler( $callback );
public static function handleFault( $faultcode, $faultstring, $faultdetail );
public static function userInfo( User $user );
}
Now I have several classes that implement this interface and I want to call several of these methods on each of those classes.
So there are 2 ways I can invoke those methods. The pre-5.3 version:
call_user_func_array( array( $provider, "registerSoapTypes" ), array( $server->wsdl ) );
And the post-5.3 version:
$provider::registerSoapTypes( $server->wsdl );
Now, my problem is, the pre-5.3 version doesn't work at all in 5.3.3.
Parameter 1 to Foo::registerSoapTypes() expected to be a reference, value given
Even though I am pretty sure it worked fine with 5.3.0. The d开发者_JAVA技巧ocumentation also states:
Referenced variables in param_arr are passed to the function by reference, regardless of whether the function expects the respective parameter to be passed by reference. This form of call-time pass by reference does not emit a deprecation notice, but it is nonetheless deprecated, and will most likely be removed in the next version of PHP.
So I thought I was being real smart by cooking this up:
$soapProvider = array( "Foo", "Bar", "Foo2", "Bar2" );
foreach( $soapProvider as $provider ) {
if( !defined( "PHP_VERSION_ID" ) ) {
$version = explode( ".", PHP_VERSION );
define( "PHP_VERSION_ID", ( $version[ 0 ] * 10000 + $version[ 1 ] * 100 + $version[ 2 ] ) );
}
if( PHP_VERSION_ID > 50300 ) {
// Use simple calling method on systems running PHP 5.3.0 or higher
$provider::registerSoapTypes( $server->wsdl );
$provider::registerSoapOperations( $server );
$provider::registerFaultHandler( "faultHandler" );
$provider::userInfo( $user );
} else {
call_user_func_array( array( $provider, "registerSoapTypes" ), array( $server->wsdl ) );
call_user_func_array( array( $provider, "registerSoapOperations" ), array( $server ) );
call_user_func_array( array( $provider, "registerFaultHandler" ), array( "faulthandler" ) );
call_user_func_array( array( $provider, "userInfo" ), array( $user ) );
}
}
Turns out, it wasn't smart at all, as $provider::something()
generates a parser error (Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM
).
So, what is the way of calling those static methods on those classes (when the class name is provider as a string) that works on PHP 5.2.6 (Debian 5) through 5.3.3 (Debian 6).
As Znarkus wrote, you're not passing a reference to Foo::registerSoapTypes
,
so just add an & to those parameters that need to be passed as references, in the second parameter of your call_user_func_array
call_user_func_array( array( $provider, "registerSoapTypes" ), array( &$server->wsdl ) );
But if not all your methods expects the parameters to be a reference, you could run into some problems, so maybe it's safer to construct the $args for call_user_func_array
using some reflection.
See: http://www.php.net/manual/en/book.reflection.php
and especially: http://www.php.net/manual/en/reflectionparameter.ispassedbyreference.php
Parameter 1 to Foo::registerSoapTypes() expected to be a reference, value given
Using call_user_func
instead of call_user_func_array
should fix that.
精彩评论