"Fatal Error" has always been the bane of my world because there is no way to capture and handle the condition in PHP. My team builds almost everything in PHP in order to leverage our core library of code, so it was of the essence to find a solution for this problem of scripts bombing unrecoverably and us never knowing about it.
One of our background automation systems creates a "task queue" of sorts and for each task in the queue, a PHP module is include()ed to handle the task. Sometimes however a poorly behaved module will nuke with a Fatal Error and take out the parent script with it.
I decided to try to use pcntl_fork() to isolate the task module from the parent code, and it seems to work: a Fatal Error generated within the module makes the child task bomb, and the waiting parent can simply catch the return code from the child and track/alert us to the problem as needed.
Naturally something similar could be done if I wanted to simply exec() the module and check the output, but then I would not have the benefit of the stateful environment that the parent script has so carefully prepared. This allows me to keep the child process within the context of the parent's running environment and not suffer the consequences of Fatal Errors stopping the task queue from continuing to process.
Here is fork_n_wait.php for your amusement:
<?php
if (! function_exists('pcntl_fork')) die('PCNTL functions not available on this PHP installation');
for ($x = 1; $x < 5; $x++) {
switch ($pid = pcntl_fork()) {
case -1:
die('Fork failed');
break;
case 0:
print "FORK: Child #{$x} preparing to nuke...\n";
generate_fatal_error(); break;
default:
print "FORK: Parent, letting the child run amok...\n";
pcntl_waitpid($pid, $status);
break;
}
}
print "Done! :^)\n\n";
?>
Which outputs:
php -q fork_n_wait.php
FORK: Child #1 preparing to nuke...
PHP Fatal error: Call to undefined function generate_fatal_error() in ~fork_n_wait.php on line 16
FORK: Parent, letting the child run amok...
FORK: Child #2 preparing to nuke...
PHP Fatal error: Call to undefined function generate_fatal_error() in ~/fork_n_wait.php on line 16
FORK: Parent, letting the child run amok...
FORK: Child #3 preparing to nuke...
PHP Fatal error: Call to undefined function generate_fatal_error() in ~/fork_n_wait.php on line 16
FORK: Parent, letting the child run amok...
FORK: Child #4 preparing to nuke...
PHP Fatal error: Call to undefined function generate_fatal_error() in ~/fork_n_wait.php on line 16
FORK: Parent, letting the child run amok...
Done! :^)