如何将 is_callable 与 __call 一起使用?

Posted

技术标签:

【中文标题】如何将 is_callable 与 __call 一起使用?【英文标题】:How to use is_callable with __call? 【发布时间】:2011-08-21 20:25:57 【问题描述】:

我使用 php 5.3,它引入了闭包。因为我现在在整个应用程序(和框架)中都有可用的闭包,所以我使用 is_callable 来查看 $callback 是什么类型的处理程序。

如果$callbackis_callable,我足够了解并使用该函数/方法/闭包。如果它不可调用并且是一个字符串,那么它可能是$this 类中的方法名称。它可能存在,也可能不存在。如果我把它交给 PHP,它会“抛出”一个很好的致命错误(我喜欢那些)。

但我想使用mix-ins,这意味着我需要魔术方法__call__call 非常酷,因为它(可以)在实际函数调用之前包含逻辑。 但是...如果在__call 之后被调用的方法不存在怎么办?当然,我可以抛出异常,但我们要等到之后才能知道。

现在的问题是is_callable 的用处,因为在实现__call 之后,everything 将返回true,因为所有东西都有一个回退(__call)。

有没有办法兼得:动态方法和有用的is_callable

我希望看到某种可缓存的魔术方法__is_callable,当调用is_callable(array($object, $method)) 时,PHP 将“咨询”。

在 php.net 上,我找不到像我一样对此感到困惑的人。这不可能!如果你用__call,你就不能再用is_callable了!?

我说的有道理吗?

PS。我已经查看了 method_exists 但这还不够好(即使我可以过滤掉所有闭包和全局函数),因为它会为私有和受保护的方法返回 true以及公开的。

编辑 我做了a 'better' is_callable that checks for mix-ins,但我觉得它很贵。

【问题讨论】:

【参考方案1】:

第一个想法:如何检查get_class_methods() 中是否存在方法?此函数负责处理范围问题。

第二个想法:如果您要查找的函数在类中不存在,您还可以检查(使用method_exists)类是否包含__call 魔术方法,如果它不明显调用不存在的功能是非法的。如果类包含__call 方法,调用者很可能知道他在做什么。

这些只是我的想法,我认为 Python 在这类事情上会更好。

【讨论】:

get_class_methods 确实解决了另一个问题,但并不是真正的混合。这个非常重要的部分并不是真的:“如果类包含__call 方法,那么调用者很可能知道他在做什么。”因为您可能会为 10 个类设置一个渲染器,只有 4 个类拥有(并使用)而其他 6 个将使用标准,但您现在只需设置一次。 (哇,你明白了吗?)

以上是关于如何将 is_callable 与 __call 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

php中method_exists()和is_callable()如何进行语句判断

php获取可见性

PHP __call 与 method_exists

PHP中__call()方法与重载解析

魔术方法之__call与__callStatic方法

调用 super() 时元类如何与 MRO 列表一起工作?