PHP coding tip: Convert notices and warnings into Exceptions

This coding tip demonstrates how to deal with PHP core notices and warning (aka recoverable errors) in the exception way, using try/catch statement.

The way on how PHP informs you about the errors, warnings, and notices in the script is one of the PHP messy areas. The half-way OOP changes, made in PHP 5, did not change the way on how PHP handle some runtime issues, like accessing an undefined variable or writing into read-only files. In the same time, new Exception-based error handling, which was added into the engine, provides the developers with the standard and time-proven way of dealing with exceptions in the code.

So, in the PHP programs, the developers should take care of the old-style engine messages, which can be sent by the standard functions or by the core, together with the new-style exceptions with try/catch and so on. The code with these approaches, being joined in the same application or function, looks incomplete and frequently raises a desire to rewrite it. And here is a method, which, in some cases, can help you deal with core messages as if they are exceptions.

The main idea of the method is the following: create an error handling function that throws an exception with the corresponding message and code and then catch this exception. Consider the following:

function errorHandler($errno, $errstr, $errfile, $errline) {
	throw new Exception($errstr, $errno);
}
set_error_handler('errorHandler');
try {
	file_put_contents('cosmos:\\1.txt', 'asdf');
} catch (Exception $e) {
	echo $e->getMessage();
}

The code above throws an exception because the file cannot be saved. Then the exception is caught by the try/catch statement. With a little bit of additional error processing you can create even more reliable code:

class IOException extends Exception {}

function errorHandler($errno, $errstr, $errfile, $errline) {
	if (false !== substr('failed to open stream', $errstr)) {
		throw new IOException($errstr, $errno);
	}
	throw new Exception($errstr, $errno);
}

set_error_handler('errorHandler');

try {
	file_put_contents('cosmos:\\1.txt', 'asdf');
} catch (IOException $e) {
	echo 'IO exception: ' . $e->getMessage();
} catch (Exception $e) {
	echo 'Unknown exception: ' . $e->getMessage();
}