【问题标题】:Calling static method of class by name按名称调用类的静态方法
【发布时间】:2011-08-26 15:18:36
【问题描述】:

这是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) 上工作的那些类上调用这些静态方法的方式是什么(当类名是提供者作为字符串时)。

【问题讨论】:

    标签: php php-5.3 php-5.2


    【解决方案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

    【讨论】:

    • 不知何故,我认为这也不合法。鉴于文档指出:函数调用没有参考符号 - 仅在函数定义上。仅函数定义就足以通过引用正确传递参数。从 PHP 5.3.0 开始,当您在 foo(&$a); 中使用 & 时,您将收到一条警告说“调用时传递引用”已被弃用。
    【解决方案2】:

    Foo::registerSoapTypes() 的参数 1 应该是一个引用,给定值

    使用call_user_func 而不是call_user_func_array 应该可以解决这个问题。

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-25
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多