有没有一种方法可以评估一段存在die()或exit()的php代码,并在调用时返回到主代码


is there a way to eval a piece of php code where die() or exit() is present and return to main code if it is called?

我无法控制正在执行的代码。这是第三方功能,但不是用户输入的。这些都是版本化的东西,所以我戳那里,把所有的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_redefinefunction_override来重新定义函数dieexit,从而引发异常。一个潜在的问题是,第三方可能会发现这些异常,但可能无法正确处理。你也很可能无法正确处理这个例外。

您可以在调用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);时,它会变得更加令人不快。您必须使用正则表达式来处理这些问题。

但是如果你可以放心地假设

  1. 这两个签名(die()exit())是您唯一需要担心的;以及
  2. 字符串(或其他内容)不会包含那些"短语"

那么你可以使用这种方法。