在子函数内部打破父函数(最好是PHP)

6

我面临一个挑战,如何在不修改父函数代码的情况下,使用PHP中断或结束父函数的执行。

除了在子函数中使用die();来结束所有执行并终止父函数调用后的任何内容外,我无法想出其他解决方案。有什么想法吗?

代码示例:

function victim() {
    echo "I should be run";
    killer();
    echo "I should not";
}
function killer() {
    //code to break parent here
}
victim();
echo "This should still run";

http://php.net/register_tick_function -- tick函数比较难以理解,可能会影响性能,并且文档说明也不是很清楚。但是它们允许您在每n个语句中有效地执行一个自定义的函数。这意味着您的tick函数可以在任何其他函数执行过程中间执行。 - Frank Farmer
@Frank,我很感兴趣知道这如何成为解决此“问题”的方案。请有人发布一个答案! :) - deceze
值得一提的是,runkit_function_redefine() 不喜欢在函数正在运行时重新定义它。 :) - Annika Backstrom
2个回答

7
function victim() {
    echo "I should be run";
    killer();
    echo "I should not";
}
function killer() {
    throw new Exception('Die!');
}

try {
    victim();
} catch (Exception $e) {
    // note that catch blocks shouldn't be empty :)
}
echo "This should still run";

好的,谢谢。我之前错误地认为异常会返回到 victim() 函数中。有没有不使用 try 块就能实现这种操作的方法? - Franklyn Tackitt
@Fran No(嗯,也许在内部可能是可能的,但这将非常hacky)。您可以在victim内部处理异常,在另一个函数中包装victim以处理异常,或者只需在killer中返回一个布尔值,指示执行是否应继续,并使victim尊重该值。 - Artefacto
这就是我想到的,我只是比较好奇而已。谢谢大家! - Franklyn Tackitt
如果抛出异常,代码执行会移动到堆栈中第一个适用的 catch 块。如果没有,则默认异常处理程序将捕获并停止整个脚本的执行。因此,在使用异常时,需要一个 catch 块。我现在想不出另一种解决这个“难题”的方法了。 - deceze

1
请注意,在以下情况下,异常将无法正常工作:
function victim() {
  echo "this runs";
  try {
    killer();
  }
  catch(Exception $sudden_death) {
    echo "still alive";
  }
  echo "and this runs just fine, too";
}

function killer() { throw new Exception("This is not going to work!"); }

victim();

你需要其他的东西,更加健壮的方法是安装自己的错误处理程序,确保所有错误都报告给错误处理程序,并确保错误不会转换为异常;然后触发一个错误并在完成后让你的错误处理程序终止脚本。这样,你就可以在 killer()/victim() 的上下文之外执行代码,并防止 victim() 正常完成(仅当你在错误处理程序中终止脚本时)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接