【问题标题】:PHP __call vs method_existsPHP __call 与 method_exists
【发布时间】:2010-12-03 02:30:57
【问题描述】:

我正在处理的项目包含类似于 call_user_func(_array) 的包装器,它在执行前会进行一些检查。 其中一项检查是 method_exists (如果提供的第一个参数是类的实例,第二个是方法名称) 另一个是_callable。 如果其中一项检查失败,该函数将引发异常。

我的代码包含一个带有函数名称(setFoo、setBar 等)的数组和用于重载的 php 魔术函数(__call),它处理某些变量的设置、替换和删除(更好的某些数组元素)。

问题: 如果未定义函数,method_exists 将返回 false。

如果 __call 函数正确处理请求,我是否有机会获得 true?

【问题讨论】:

  • 好问题,我会玩这个。
  • 需要的是另一种“神奇的方法” __canCall 什么的……
  • is_callable() 适用于类的实例。我根本不明白您为什么要使用 method_exists() 。 is_callable() 做了所有 method_exists() 做的事情,而且它与 __call() 一起工作。

标签: php overloading


【解决方案1】:

__call 处理对不存在的方法的调用。 method_exists 是一种检查方法是否存在的自省方法。

__call如何确定处理方法?我认为您必须在 __call 中手动抛出异常,如果不处理您的请求并在代码中捕获异常,否则将使用 method_existsBadMethodCallException 就是为此目的而存在的。

【讨论】:

  • 似乎__call 没有“失败”的概念,所以看起来像在 __call 方法中抛出一个 NotImplementedException (或类似的)将是这样做的方法。
【解决方案2】:

看看is_callable()

但是不,如果__call() 方法只处理一些名称,那么您将需要其他方法来检查调用是否成功。

我可以建议使用canCall($function) 方法的接口,还是什么?然后检查该类是否实现了该接口。如果没有,请使用is_callable()

【讨论】:

  • is_callable() 如果定义了 __call() 会自动返回 true,使得 is_callable() 不可靠(因为它不能确保 __call() 满足请求)
【解决方案3】:

method_exists 尝试了两件事:

  • 在类的函数表中搜索方法名称。
    这些是function foo() {} 类型的方法。
  • 检查类(C 代码)是否有(C 代码)get_method() 函数,以及是否调用它让类实现决定。

你需要后者。但是这个get_method()没有“扩展”到 PHP 脚本代码,也就是说,没有办法让 get_method() 调用一些用户定义的 PHP 脚本代码(这个 PHP 代码会返回什么?)。

因此,据我所知,答案是:不,这是不可能的(还没有?)。

ZEND_FUNCTION(method_exists) 的实现可以在zend/zend_builtin_functions.c 中找到,我认为即使你不懂 C 而懂 PHP,也相当易读。

【讨论】:

    【解决方案4】:

    如果你真的确定 _call 总是有一个后备,你可以这样做:

    if (method_exists($this, $method_name) || method_exists($this, '__call')) {
      // Call of the method
    }
    

    【讨论】:

      【解决方案5】:

      我很想在你的 __call 函数中使用 method_existsthrowException 如果这失败并将所有内容包装在 try catch 块中,而不是使用 is_callable功能。

      【讨论】:

        猜你喜欢
        • 2012-11-12
        • 2011-08-02
        • 1970-01-01
        • 2018-12-24
        • 1970-01-01
        • 2016-10-21
        • 1970-01-01
        • 2011-03-20
        • 2011-07-08
        相关资源
        最近更新 更多