【发布时间】:2016-02-23 20:27:02
【问题描述】:
PHP 有其神奇的方法__call 和__callStatic,它们允许拦截对不存在的方法 的调用。我正在寻找一种方法来拦截对不存在的 function (位于命名空间内的函数,而不是类型)的调用。
可以做(PHP7)吗?
我曾经考虑过将函数放在代理类中,但是命名空间可以跨越多个文件,如果我没记错的话,PHP 没有部分类,因此这种方法没有用。
更新:每个命名空间有多个文件问题。
假设我有文件 A.php 和 B.php,它们都具有相同的命名空间,例如 Text。考虑将所有功能放到代理类中。现在我有文件 C.php,我打电话给Text\indexOf(...)。但是我不知道这是Text\proxyA::indexOf 还是Text\proxyB::indexOf,因为我拥有的所有信息都是命名空间的名称——Text——和函数名称。所以从调用者的角度来看,我很高兴。
【问题讨论】:
-
如果“拦截”是指“通过返回我自己选择的值使呼叫正常解决”,那么不,这是不可能的。但我真的很好奇——用例会是什么?
-
@Jon,拦截我的意思是
__callStatic所做的只有一个区别——目标是命名空间而不是类型。目的,我正在研究类似于 C++ 中的模板的东西,我会拦截一个函数调用,对名称进行分解,然后调用函数工厂,它会生成(然后调用)函数的专用版本(我使用 PHP 作为我的后端语言:aboutskila.wordpress.com)。 -
好吧,如果你需要这个特性,那你为什么要编译直接函数调用呢?您可以改为编译为
resolve_function_call('mangled_name', ['argument', 'list'])并解决问题。或者甚至用专门为此目的制作的类型上的静态方法调用替换裸函数调用,这将用__callStatic拦截它们。 -
@Jon,是的,这就是我现在正在考虑的——我正在寻找拦截,因为它已经用于模板类型,所以我更愿意使用相同的机制(更少的代码=更少的错误)。当然,如果不可能,我会为类型和函数实现两种不同的方式。至于静态方法作为我已经写过的伪装函数——不可能,每个命名空间可以有多个文件。您能否将您的最后一条评论作为常规答案发表?谢谢。
-
另外,我还有一个想法。您可以利用自动加载和代理类的想法来实现 codegen-once-then-always-call-without-overhead。我做了一个PoChere,可能更接近你的想象?
标签: php