What you must know about PHP errors to avoid scratching your forehead when something goes wrong
Join the DZone community and get the full member experience.
Join For FreeWhile pure object-oriented languages produce mainly exceptions to signal an error, PHP started out as procedural and so it has a wide range of errors that can be raised along with exceptions.
Errors are Human, But We Must Identify Them
There isn’t a programmer alive who hasn’t made errors when coding something at some point in their career. It is simply a part of the process, and it is important to recognize that we will all make these types of mistakes from time to time. That said, it is best to identify the errors as they occur so as to correct them at the moment.
The faster that one can react to the errors that they are making, the better they will be able to correct those same errors and actually make a difference in the programming that they are doing. Put another way, it may be necessary to move rapidly to correct errors so that the project itself doesn’t get knocked off kilter at all.
It is all up to you as to how you will move forward when you spot errors, but the best thing to do is remind yourself that this is expected and that you can do things to correct it.
What is the difference between the two?
Exceptions are objects which can be managed and caught with try/catch blocks. You can create your own exception classes, with custom arguments and methods. They really object with special additional functionalities and you should definitely manage your error with them in PHP 5 and higher.
Errors are accompanied by a message like exceptions, but they are managed by calling an error handler function (which may be custom) from the point when they occur. PHP and its native functions generate mostly errors and not exceptions. PDO and the SPL are the exceptions (what a pun) since they have an object-oriented Api which also comprehends exception classes.
Exceptions always bubble up until they are caught; errors are instead passed to the current error handler, whose job is to decide what to do with them. With non-severe errors, printing them in bold and going on with execution is the default behavior.
Understanding exceptions and their usage is a key topic in transitioning to object-oriented PHP, but is out of the scope of this article. Here we will treat errors since you'll always have to deal with PHP native functions even if your code is so good it only throws exceptions to your custom hierarchy: when you omit a {, an error is generated, not an exception. When a file passed to include() is missing, again an error is generated, not an exception.
Most of the time unhandled errors are the result of a programming error: if you get an error to be generated, probably something is already gone really wrong and you shouldn't ignore them.
Translation into exceptions
However, dealing with errors in an object-oriented way is very difficult: you can't catch them. Thus PHPUnit translates errors into exceptions by defining a custom error handler that throws PHPUnit_Frameworks_Error_Notice or PHPUnit_Framework_Error_Warning in case of manageable errors.
PHPUnit will also signal you with an E in the test base in case of an error, while the F is reserved for particular exceptions that designate assertion failures.
Nothing stops you from doing the same: by defining your error handler, you can translate the errors of missing files in include() into an exception you can catch. The question is: shall you? Often a missing file, when containing for example the source code of a class, will only result in a more serious error like a Fatl one when the script is allowed to continue.
Main error types
These are the main types of errors, which were present in the language before PHP 4. The majority of the time during development, you'll only see one of these four error types.
E_NOTICE: a noncritical error, like accessing an initialized variable. PHP is very forgiving and will allow the script to continue in production environments.
E_WARNING: a more serious error, like passing a non-Traversable to foreach(), or including a missing file.
E_PARSE: a syntax error, like a missing } or using a reserved keyword for naming a class. The script won't run at all as these errors are raised at compile (to p codes) time.
E_ERROR: also known as Fatal Errors, they are unrecoverable even by the error handler. Calling a method on null, or calling an undefined function, or creating an object of a non-existing class would result in a Fatal Error, which will terminate the script abruptly (even if it is a test suite!)
There are many other types of errors, but they are rarer to encounter. The full list is in the PHP manual.
From the list, some interesting special errors should be mentioned:
E_STRICT: infringement of strict standards, which from PHP 5.3 it is in the default. If you call a non-static method statically (by Class::method()), you will get this error. Enabling strict standards can help you improve your code quality.
E_RECOVERABLE_ERROR: a catchable version of Fatal Error, such as trying to convert an object without __toString() into a string. It can be managed by error handlers, while Fatal Errors and of course Parse Errors can't (they leave the interpreter in an unstable state and cause an immediate exit()).
php.ini directives
There are two directives that are very interesting for managing errors.
The first is error_reporting, which prescribes reporting some types of errors while masking others. Typically this value varies between production environments (don't show anything to the end user as it won't understand anyway) and development environments (show me everything as I want to eliminate all errors before shipping.)
In fact, in development, I always set error_reporting to E_ALL. Anything else is so '90s.
display_errors has also to be set to On for the errors to be printed. When you get a blank page instead of the expected result, check this directive.
PHP functions
error_reporting() allows you to set which errors to report and override the error_reporting in php.ini, again by using E_ALL and other constants. Note that some errors, like E_PARSE, are detected at compile time and so won't be influenced by this function.
set_error_handler() allows you to define your own function to manage errors, which can then delegate to PHP default handler or completely override it.
Take-home points
Errors are a tricky part of PHP, but knowing how to read them will speed up your development. In your code, always define exceptions, which are much more versatile, but be prepared to manage errors thrown by PHP itself.
Most of the time, they're just programming errors like a typo in a variable name or a missing semicolon. However, you should know how to define custom error handlers in case you're forced to deal with runtime errors like a problem with a socket or a database connection.
Opinions expressed by DZone contributors are their own.
Comments