我无法控制正在执行的代码。这是第三方功能,但不是用户输入的。这些都是版本化的东西,所以我戳那里,把所有的die()都改成更理智的东西是不切实际的。因为一个新版本不时出现,然后我可能会通过糟糕的错误处理来让代码变得更加不安全。
假设我们有一个函数:
fuction myfunc() {
// lot's of complicated code
if (!is_file('myfile.txt') exit('file not found');
// and so on
}
我想做的是在某种程度上运行这段代码并返回到我的主线程,然后对该错误采取相应的操作。
我尝试过die()
或eval()
,但这会返回整个脚本。真倒霉
一种万无一失的方法是使用runkit的runkit_function_redefine
或function_override
来重新定义函数die
和exit
,从而引发异常。一个潜在的问题是,第三方可能会发现这些异常,但可能无法正确处理。你也很可能无法正确处理这个例外。
您可以在调用exit
之后使用register_shutdown_function
来运行代码。在这一点上,您所能做的有些有限,因为一些服务已经关闭(例如自动加载)。我认为您仍然可以输出内容,不确定会话和其他标头。
另一种方法是在单独的php进程(或http请求)中运行代码,例如通过exec
调用php。
一种更可靠的方法是在您自己的代码中添加预引用,确保在调用第三方代码时永远不会达到坏状态。可能并非所有先决条件都能得到满足。
理想情况下,只有作为入口点的代码(如路由器脚本)才能exit
。在其他地方使用exit
实际上只是粗制滥造的编程。
如果你还没有读过Halcyon的答案,你应该先看看。
既然您提到了eval()
,我假设您的代码是字符串。我将用后者来指代die()
和exit()
,但事情应该与两者相关。
您可以尝试用一些东西替换die()和exit()的出现,然后进行eval。这很简单,但可能很混乱。
如果你决定这样做,需要注意的一件事是,你最终可能会替换不是真正"代码"的出现。例如,echo "Let him exit()";
。
此外,当您考虑可能的等效语法,如exit ();
、exit;
或exit(1);
时,它会变得更加令人不快。您必须使用正则表达式来处理这些问题。
但是如果你可以放心地假设
- 这两个签名(
die()
和exit()
)是您唯一需要担心的;以及 - 字符串(或其他内容)不会包含那些"短语"
那么你可以使用这种方法。