【问题标题】:__call method needs to know when to pass var by reference or by value__call 方法需要知道何时通过引用或值传递 var
【发布时间】:2013-10-10 00:34:27
【问题描述】:

我有一个对象,它使用神奇的 __call 方法来调用不同对象的方法。

有时此方法将用于调用需要其一个或多个参数作为引用的方法。

从 php 5.3 开始,调用时传递引用已被弃用,因此我不能依赖通过引用传递参数。我需要预测参数是否需要通过引用或值传递!

我将尝试在代码中解释这一点。我有以下两个类:

  • Main_Object
  • Extension_Object

注意:两个类之间没有继承结构。

class Main_Object  {

 public function __call($method, $arguments)
 {
  // check this method is in an extended class
  // …

  $ext = new Extension_Object();

  // call method in extension object
  return call_user_func_array(array($ext, $method), $arguments);
 }
}

class Extension_Object {

 // takes two arguments
 public function foo($p1, $p2)
 {
  // ...
 }

 // takes two arguments, the first being a reference
 public function bar(&$p1, $p2)
 {
  // ...
 }
}

目前我找不到在不产生 PHP 错误或警告的情况下调用 bar() 的方法

$obj = new Main_Object();

// works as expected
$obj->foo($bacon, $cheese);

// MESSAGE call-time pass-by-reference has been deprecated
$obj->bar(&$bacon, $cheese);

// WARNING parameter 1 expected to be a reference
$obj->bar($bacon, $cheese);

【问题讨论】:

  • 为什么要传递引用?根据我的经验,99% 的引用使用实际上是完全可行的,无需使用引用...所以除非您有需要使用引用,否则我不会担心...
  • 感谢您的提醒。我需要传递对对象的引用,因为该方法可能会更改其某些属性。我无法返回对象,因为该方法需要返回其他内容。我可以返回一个值数组并使用 list() 将返回的元素分配给它们自己的变量,但这感觉很脏。
  • 您不需要参考。在 PHP 5.0+ 中,对象仅通过引用传递(您需要显式地clone 对象来中断引用)。见the docs on the subject。所以不,你不需要通过引用传递......
  • 啊,谢谢。那解决它!

标签: php


【解决方案1】:

你可以设置 allow_call_time_pass_reference = 1;但这远非一个好的解决方案。好像没有别的办法了。反思可能会产生一个答案,但我个人对这个特定问题知之甚少,无法就此提出真正的建议......

Is it possible to pass parameters by reference using call_user_func_array()?

PHP: call_user_func_array: pass by reference issue

【讨论】:

    【解决方案2】:

    您可以像这样手动转换参数。

    public function __call($method, $arguments) {
      $referenceable_arguments = array();
      // Gets around a limitation in PHP.
      foreach ($arguments as &$argument) {
        $referenceable_arguments[] = &$argument;
      }
      return call_user_func_array(array($this->delegate, $method), $referenceable_arguments);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 2013-06-20
      • 2011-09-27
      • 2016-05-04
      • 1970-01-01
      相关资源
      最近更新 更多