【问题标题】:PHP Call-time pass-by-reference unavoidable?PHP Call-time pass-by-reference 不可避免?
【发布时间】:2010-10-19 13:27:21
【问题描述】:

给定如下界面:

interface ISoapInterface {
  public static function registerSoapTypes( &$wsdl );
  public static function registerSoapOperations( &$server );
}

还有如下代码:

$soapProvider = array( "FilePool", "UserList" );
foreach( $soapProvider as $provider ) {
  call_user_func( array( $provider, "registerSoapTypes" ), &$server->wsdl );
  call_user_func( array( $provider, "registerSoapOperations" ), &$server );
}

FilePoolUserList 都实现了ISoapInterface

PHP 会抱怨 foreach 中的两个调用:

调用时传递引用已被弃用

所以我查看了这条消息,the documentation 似乎很清楚如何解决这个问题。从实际调用中删除与号。
所以我把我的代码改成这样:

$soapProvider = array( "FilePool", "UserList" );
foreach( $soapProvider as $provider ) {
  call_user_func( array( $provider, "registerSoapTypes" ), $server->wsdl );
  call_user_func( array( $provider, "registerSoapOperations" ), $server );
}

现在 PHP 抱怨

FilePool::registerSoapTypes 的参数 1 应为参考,给定值
FilePool::registerSoapOperations 的参数 1 应为参考,给定值

除此之外,该功能现在已损坏。所以这显然不能成为解决方案。

【问题讨论】:

    标签: php pass-by-reference


    【解决方案1】:

    来自call_user_func

    注意 call_user_func() 的参数不是通过引用传递的。

    要调用静态方法,您可以使用Class::method() 语法,为Class 和/或method 部分提供变量:

    $soapProvider = array( "FilePool", "UserList" );
    foreach( $soapProvider as $provider ) {
      $provider::registerSoapTypes($server->wsdl);
      $provider::registerSoapOperations($server);
    }
    

    【讨论】:

    • 如果我使用 $provider->registerSoapTypes,我会在非对象上调用成员函数 registerSoapTypes。方法是静态的。如果我没记错的话,这就是最初导致我调用 call_user_func 的原因。
    • @gencha 我错过了static;将相应地更新我的答案。
    【解决方案2】:

    虽然call_user_func 不通过引用传递参数,但call_user_func_array 可以。

    $callback = array($provider, 'blahblahblah');
    call_user_func_array($callback, array( &$server ));
    

    唯一真正的区别是它需要一个参数数组而不是像call_user_func 这样的参数列表(类似于sprintfvsprintf 之间的区别)...

    【讨论】:

    • 这实际上工作得很好,我只是想知道我是否遗漏了一些关于 meagar 的解决方案。谢谢
    • 好吧,@meagar 的解决方案很好。它只是直接调用该方法,而不是调用一个函数来完成它。这就像做$object->method(),但对于静态方法class::method()$className::method() 其中$className 包含类的字符串名称(如在您的原始代码中)。两种解决方案都可以正常工作。 @meagar 更快更高效,但我的更灵活($callback 可以是任何东西,参数的数量可以是可变的)。两者都有效...
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 2015-03-07
    • 2013-11-08
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    相关资源
    最近更新 更多