views:

56

answers:

2

I was challenged how to break or end execution of a parent function without modifying the code of the parent, using PHP

I cannot figure out any solution, other than die(); in the child, which would end all execution, and so anything after the parent function call would end. Any ideas?

code example:

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";
+3  A: 
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";
deceze
ok thanks, i thought for some reason the exception would return to victim();. is there any way to do such a thing without the try block?
Franklyn Tackitt
@Fran No (well, maybe internally it's possible, but it would be very hacky). You could handle the exception inside victim, wrap victim in an other function that would handle the exception or just return a boolean value in killer that says whether the execution should continue and have victim respect that.
Artefacto
Thats what i figured, i was more curious that anything. thanks guys!
Franklyn Tackitt
If an exception is thrown, the code execution moves to the first applicable `catch` block up the stack. If there is non, the default exception handler will catch it and halt the whole script. So, when using exceptions, you need a `catch` block. I couldn't think of another way to solve this "puzzle" right now.
deceze
A: 

Note that Exceptions are not going to work in the following scenario:

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();

You would need something else, the only thing more robust would be something like installing your own error handler, ensure all errors are reported to the error handler and ensure errors are not converted to exceptions; then trigger an error and have your error handler kill the script when done. This way you can execute code outside of the context of killer()/victim() and prevent victim() from completing normally (only if you do kill the script as part of your error handler).