为非对象模拟__call()

时间:2013-08-30 18:08:33

标签: php magic-methods

以下示例肯定会输出错误:

$myVar = "hello";
$var->exeptionForSure();

==> Fatal error: Call to a member function exeptionForSure() on a non-object in..

有没有办法可以模拟/实现魔术方法__call()以便在这种情况下工作?

我希望能够调用我自己的函数,如果由于某种原因我尝试访问非对象中的方法。

3 个答案:

答案 0 :(得分:1)

在PHP中没有这方面的设施,可能永远不会有。

任何这样的方法都必须在PHP脚本的持续时间内全局存在(它没有在其中运行的类上下文),并且它的存在可能会使代码复杂化以满足这种不寻常的要求。

这也意味着一些略微奇怪的范围规则:假设$non_object->method(42);被翻译为magic_non_object_call($non_object, 'method', array(42));,左手操作数($non_object)必须通过值传递(在这种情况下,它无法写回)或通过引用(这要求PHP放弃对该变量的“写时复制”内存优化)。请注意,对象用附加的抽象层表示,因此$this(以及“按值”传递或复制的对象)实际上包含句柄到“真实”对象,避免这种情况确切的问题。

从根本上说,你需要这样做的唯一原因是作为“最后沟”错误处理程序 - 如果你的代码无法判断某个给定变量是否是一个对象,那就是一个bug。不幸的是,这是致命错误,所以我认为你不能抓住/处理它。 (注意它是一个异常;很少有PHP内置函数抛出异常。)

答案 1 :(得分:0)

这应该有效:

method_exists($var, 'exeptionForSure') ? $var->exeptionForSure() : fallback();

您还可以为您的对象定义与上述相同的特定方法,以便您可以执行以下操作:

$obj->call_func('func_name', $params);

答案 2 :(得分:0)

只有对象具有可以调用的方法。在PHP中,字符串,数字等不是对象,因此您无法在它们上定义或调用方法。

method_exists检查给定对象是否存在某种方法。但是你不应该为非对象调用这个函数。

首先,你应该检查$ var是否是一个对象:

if (is_object($var) && method_exists($var, 'exeptionForSure')) {
   $var->exeptionForSure();
} else {
   fallback(); 
}