Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 是否可以拦截对不存在函数的调用?_Php - Fatal编程技术网

Php 是否可以拦截对不存在函数的调用?

Php 是否可以拦截对不存在函数的调用?,php,Php,PHP有其神奇的方法\uuuu call和\uuuu callStatic,它们允许拦截对不存在的方法的调用。我正在寻找一种方法来拦截对不存在的函数的调用(位于名称空间中的函数,而不是类型) 有可能吗(PHP7) 有一段时间,我考虑将函数放在代理类中,但名称空间可以跨越多个文件,如果我没有弄错的话,PHP没有分部类,因此这种方法没有用处 更新:每个命名空间问题有多个文件 假设我有文件A.php和B.php,它们都具有相同的名称空间,比如Text。考虑将所有的函数放到代理类中。现在我有了文件C.p

PHP有其神奇的方法
\uuuu call
\uuuu callStatic
,它们允许拦截对不存在的方法的调用。我正在寻找一种方法来拦截对不存在的函数的调用(位于名称空间中的函数,而不是类型)

有可能吗(PHP7)

有一段时间,我考虑将函数放在代理类中,但名称空间可以跨越多个文件,如果我没有弄错的话,PHP没有分部类,因此这种方法没有用处

更新:每个命名空间问题有多个文件


假设我有文件A.php和B.php,它们都具有相同的名称空间,比如
Text
。考虑将所有的函数放到代理类中。现在我有了文件C.php,我有了call
Text\indexOf(…)
。但是我不知道这是
Text\proxyA::indexOf
还是
Text\proxyB::indexOf
,因为我所有的信息都是名称空间的名称--
Text
--和函数名。因此,从调用方的角度来看,我很受欢迎。

从PHP7开始,您可以捕获未定义的函数调用:

try {
    idontexist();
} catch (\Error $e) {
    echo $e->getMessage();
}
除了通过自定义错误处理程序之外,没有任何方法可以像调用
\uuu
一样使用它


演示:

使用PHP7+可以捕获对未定义函数的调用:

try {
    not_exist();
} catch (\Error $e) {
    echo 'ERROR: ' . $e->getMessage();
}
然后,您可以使用
set\u exception\u handler
捕获该异常,而无需将其置于
try
/
catch
块中:

set_exception_handler(function($e) {
    echo '<BR>ERROR: ' . $e->getMessage();
});

not_exist();
设置异常处理程序(函数($e){
回显“
错误:”。$e->getMessage(); }); 不存在;

请注意,您需要使用
set\u exception\u handler
而不是
set\u error\u handler

谢谢,但实际上这并不可行——因为您必须在try-catch中包装每个函数调用,您还必须真正注意异常及其堆栈——您可能会调用现有函数,但是这个函数调用了一个你忘记包装的不存在的函数。你没有错,但不幸的是,这就是你要处理的全部内容。如果“intercept”的意思是“通过返回我自己选择的值使调用正常解析”,那么不,这是不可能的。但我真的很好奇——用例会是什么?@Jon,我所说的intercept正是
\uuu callStatic
所做的,只有一个区别——目标不是名称空间类型。其目的是,我在C++中使用类似于模板的一些东西,我会截取函数调用、解散名称,调用函数工厂,它产生(然后调用)函数的专业版本(我用PHP作为我的语言的后端):如果您需要此功能,那么首先为什么要编译以直接调用函数?您可以编译为
解析函数调用('mangled_name',['argument','list'])
并解决问题。或者甚至用静态方法调用来替换裸函数调用,而静态方法调用是专门为此目的而生成的,这将使用
\uu callStatic
@Jon拦截它们,是的,这就是我现在正在考虑的——我正在寻找拦截,因为它已经是我用于模板类型的方法,所以我更愿意使用相同的机制(更少的代码=更少的bug)。当然,如果不可能,我会为类型和函数实现两种不同的方法。至于我已经编写的diguise中作为函数的静态方法——不可能,每个命名空间可以有多个文件。请您将您的最后一条评论作为常规答复发布好吗?谢谢。另外,我还有一个想法。您可以利用自动加载tog以太与代理类的想法实现codegen一次,然后总是调用没有开销。我做了一个PoC,也许这更接近你的想象?谢谢你,但你仍然需要编写try-catch,更糟糕的是,使用fake
catch
子句来避免捕获异常。由于异常是昂贵的机制,这不会增加任何东西ng对于上一个答案来说真的很新。为什么还需要编写catch?什么是假catch?“如果在try/catch块中未捕获异常,则设置默认异常处理程序。”。这意味着try-catch必须首先存在(否则程序崩溃),所以我必须试着捕捉,只有这样它才不会捕捉那个异常。老实说,这和你说的不一样。