For (most) non-fatals, yes, set_error_handler
can catch those and you can handle them gracefully.
For fatal errors, take a look at the answer on this question: PHP : Custom error handler - handling parse & fatal errors
Now if you're interested in preventing simple parse errors, you can use runkit_lint_file
of the runkit extension if you're able to install extensions for your PHP installation. [Addendum edit: That is, lint the file before including it. Parse errors are not recoverable. This can also be done by running php on the command line with the -l option. Though depending on how your host is set up, you may need to modify the environment for the command-line php option to work.]
Here's an example with command line php, I'm not sure if it's a good example though. Ripped from one of my projects with some added comments.
/**
* Lint and and retrieve the result of a file. (If lint is possible)
* @param $file
* @return Mixed bool false on error, string on success.
*/
function lint_and_include ($file) {
if(is_readable($file)) {
//Unset everything except PATH.
//I do this to prevent CGI execution if we call
//a CGI version of PHP.
//Someone tell me if this is overkill please.
foreach($_ENV as $key=>$value)
{
if($key == "PATH") { continue; }
putenv($key);
}
$sfile = escapeshellarg($file);
$output = $ret = NULL;
//You could modify this to call mandatory includes to
//also catch stuff like redefined functions and the like.
//As it is here, it'll only catch syntax errors.
//You might also want to point it to the CLI php executable.
exec("php -l $sfile", $output, $return);
if($return == 0) {
//Lint Okay
ob_start();
include $file;
return ob_get_clean();
}
else {
return false;
}
}
else {
return false;
}
}
Additional note(s): In this case, your set_error_handler
callback should log the errors it can catch somewhere instead of outputting them. If any of the included code may throw exceptions, you may want to catch those as well with a try-catch block.