【问题标题】:__call magic creating new classes in PHP__call 魔术在 PHP 中创建新类
【发布时间】:2010-09-07 11:32:10
【问题描述】:

我在我的一些 mvc 代码中使用 __call 魔法来生成一个可自动加载的表单框架,但我遇到了一个问题,我希望这里有人可以解决这个问题。

__call 魔法有两个参数:$methodName 和 $arguments。参数作为您调用的 args 数组返回。通常,此函数会在您可以这样做的方法上调用,因此将这些参数输入到函数中:

call_user_func_array($methodName, $arguments);

这将使用参数传播方法签名。我正在尝试做一些更复杂的事情。我试图以相同的方式传播一个类构造函数,通过能够将一个内爆的逗号分隔的参数数组发送到类构造函数中,或者直接发送参数,但这两者都不会产生所需的结果。当我将一个内爆数组向下发送到构造函数时,PHP 认为它是一个字符串,而当我发送数组时它认为它是一个数组。

这是我使用 atm 的代码:

public function __call($method, $args){

    return $this->init_element(new $method($args['name'], $args['value'], $args['opts']));

}

如果我有 4 个参数要传递怎么办?有没有办法让它像使用 call_user_func_array() 的函数一样动态填充构造函数?

我可以使用 attributes() 函数来执行此操作,但我真的希望能够像使用函数一样执行此操作。

提前致谢,

【问题讨论】:

标签: php class constructor call


【解决方案1】:

使用 PHP 的反射类:(http://php.net/manual/en/class.reflectionclass.php)

$obj = new ReflectionClass( $classname );

然后

$ins = $obj->newInstanceArgs( $arguments );

$ins = $obj->newInstance( );

【讨论】:

  • 这个函数的速度是多少?我知道反射会很慢?
  • @Sammaye 如果您认为它会显着降低速度,请在您的应用中对其进行基准测试
  • 当我建立了一个测试并且我看到了这个stackoverflow.com/questions/294582/… 它指出只要我小心并且只在请求/调度中使用它我应该没问题,因为 __call 是调度程序我不应该真的感到压力,唯一的事情是每次我创建一个新的表单元素时它都会调度。我要运行一个基准测试,看看会发生什么。
  • @Sammaye 很有可能,没有反射代码的 __call 调用也不是很快。魔术方法也伴随着减速。最大的问题是重要吗?
  • 如果我已经在使用 _call no...所以只要我不需要制作真正巨大的表单...但是 PHP 可以在正确的服务器上处理很多事情所以它可能完全没问题,我可能只是偏执于什么。
【解决方案2】:

我在网上某处看到以下内容:

 call_user_func_array(array($obj, '__construct'), $args);

【讨论】:

  • 有人能解释一下为什么这被标记了,因为据我所知,这不仅与反射相同的速度(如果不是快一点)而且似乎没有任何真实的安全方面的副作用。有人能告诉我为什么这被降价了吗?
  • @Sammaye 投反对票的不是我,但我会说它是 dv'ed,因为它不起作用。在现有实例上调用 __construct 是没有意义的,并且提供类名而不是 $obj 将产生警告并且没有实例。如果你想call_user_func_array 给类一个静态工厂方法并调用它。
  • 是的,这可能很好,我需要在两者之间进行基准测试。
  • 我认为$obj 是该类的名称。 PHP 通常会像这样处理类成员的调用。示例:usort($someArray, array('SomeClass', 'someStaticSortFunc')).
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
相关资源
最近更新 更多