按名称调用类的静态方法

时间:2011-05-16 17:31:07

标签: php php-5.3 php-5.2

这有点是this question的第二部分。

在我的项目中,我有以下界面:

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 );
}

现在我有几个实现此接口的类,我想在每个类上调用其中的几个方法。

所以有两种方法可以调用这些方法。 5.3之前的版本:

call_user_func_array( array( $provider, "registerSoapTypes" ), array( $server->wsdl ) );

5.3之后的版本:

$provider::registerSoapTypes( $server->wsdl );

现在,我的问题是,5.3之前的版本在5.3.3中根本不起作用 Parameter 1 to Foo::registerSoapTypes() expected to be a reference, value given
虽然我很确定它在5.3.0下运行良好。 The documentation还声明:

  

param_arr中的引用变量通过引用传递给函数,无论函数是否期望通过引用传递相应的参数。这种形式的调用时间通过引用传递不会发出弃用通知,但它仍然被弃用,很可能会在下一版本的PHP中删除。

所以我认为通过烹饪来实现我的聪明才智:

$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 ) );
  }
}

事实证明,它根本不聪明,因为$provider::something()会生成解析器错误(Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM)。

那么,在PHP 5.2.6(Debian 5)到5.3.3(Debian 6)上工作的那些类上调用那些静态方法的方法(当类名是提供者作为字符串时)是什么样的。

2 个答案:

答案 0 :(得分:1)

  

参数1到Foo :: registerSoapTypes()应该是一个参考值,给定值

使用call_user_func代替call_user_func_array应该可以解决这个问题。

答案 1 :(得分:1)

正如Znarkus所写,你没有传递对Foo::registerSoapTypes

的引用

所以只需在call_user_func_array

的第二个参数中为那些需要作为参考传递的参数添加&
call_user_func_array( array( $provider, "registerSoapTypes" ), array( &$server->wsdl ) );

但是如果不是所有的方法都希望参数成为参考,那么你可能会遇到一些问题,所以使用一些反射构造call_user_func_array的$ args可能更安全。

请参阅:http://www.php.net/manual/en/book.reflection.php

特别是:http://www.php.net/manual/en/reflectionparameter.ispassedbyreference.php