mirror of
https://github.com/codeguy/php-the-right-way.git
synced 2025-08-17 19:16:20 +02:00
Closes #283: Uses orginal PR as base for a recode of Errors.
This commit is contained in:
@@ -4,52 +4,114 @@ isChild: true
|
|||||||
|
|
||||||
## Errors {#errors_title}
|
## Errors {#errors_title}
|
||||||
|
|
||||||
PHP Errors differ to Exceptions in that they, Errors can halt the execution of your script depending on the level of
|
In many "exception-heavy" programming languages, whenever anything goes wrong an exception will be thrown. This is
|
||||||
severity. Exceptions on the other hand can be caught using `try catch` statements.
|
certainly a viable way to do things, but PHP is an "exception-light" programming language. While it does have
|
||||||
|
exceptions and more of the core is starting to use them when working with objects, most of PHP itself will try to keep
|
||||||
|
processing regardless of what happens, unless a fatal error happens.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
{% highlight php %}
|
||||||
|
$ php -a
|
||||||
|
php > echo $foo;
|
||||||
|
Notice: Undefined variable: foo in php shell code on line 1
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
This is only a notice error, and PHP will happily carry on. This can be confusing for those from "exception-heavy"
|
||||||
|
languages, because referencing a missing variable in Python for example will throw an exception:
|
||||||
|
|
||||||
|
{% highlight python %}
|
||||||
|
$ python
|
||||||
|
>>> print foo
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
NameError: name 'foo' is not defined
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
The only real difference is that Python will freak out over any small thing, so that developers can be super sure any
|
||||||
|
potential issue or edge-case is caught, whereas PHP will keep on processing unless something extreme happens, at which
|
||||||
|
point it will throw an error and report it.
|
||||||
|
|
||||||
### Error Severity
|
### Error Severity
|
||||||
|
|
||||||
PHP's built in error reporting and logging, allows for different levels of reporting via the use of Predefined
|
PHP has several levels of error severity. The three most common types of messages are errors, notices and warnings.
|
||||||
Constants. The three main constants are `E_ERROR`, `E_NOTICE`, and `E_WARNING`.
|
These have different levels of severity; `E_ERROR`, `E_NOTICE`, and `E_WARNING`. Errors are fatal run-time errors and
|
||||||
|
are usually caused by faults in your code and need to be fixed as they'll cause PHP to stop executing. Warnings are
|
||||||
|
non-fatal errors, execution of the script will not be halted. Notices are advisory messages caused by code that may or
|
||||||
|
may not cause problems during the execution of the script, execution is not halted.
|
||||||
|
|
||||||
The different levels of error severity have different meanings. The three most common types of messages are Errors,
|
Another type of error message reported at compile time are `E_STRICT` messages. These messages are used to suggest
|
||||||
Notices and Warnings. Errors are fatal run-time Errors and are usually caused by faults in your code and need to be
|
changes to your code to help ensure best interoperability and forward compatibility with upcoming versions of PHP.
|
||||||
fixed as they'll cause execution to be halted. Warnings are non-fatal errors, execution of the script will continue
|
|
||||||
and dependant on settings the user may or not may see the Warning message. Notices are advisory messages caused by
|
|
||||||
code that may or may not cause problems during script execution, execution is not halted and again depending on
|
|
||||||
settings the user may or not see the Notice message.
|
|
||||||
|
|
||||||
Another type of Error Message reported at compile time are `E_STRICT` messages, these messages are used to suggest
|
|
||||||
changes to your code to help ensure best interoperability and forward compatibility for your code.
|
|
||||||
|
|
||||||
### Changing PHP's Error Reporting Behaviour
|
### Changing PHP's Error Reporting Behaviour
|
||||||
|
|
||||||
Error Reporting can both be changed using PHP settings and PHP function calls. Using the built in PHP function
|
Error Reporting can both be changed using PHP settings and PHP function calls. Using the built in PHP function
|
||||||
`error_reporting()` you can set the level of errors for the duration of the script execution by passing one of the
|
`error_reporting()` you can set the level of errors for the duration of the script execution by passing one of the
|
||||||
Predefined Constants. For more information on this relating to application environments check
|
Predefined Constants, meaning if you only want to see Warnings and Errors - but not Notices - then you can configure that:
|
||||||
out the [Error Reporting][errorreport].
|
|
||||||
|
|
||||||
As well as setting the level of error reporting during script execution you can also suppress Errors using the
|
{% highlight php %}
|
||||||
Error Control Operator `@` by putting this operator at the beginning an expression. The use of this operator
|
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||||
is not advised and should never be used, using this operator is like admitting your code is bad and can fail over
|
{% endhighlight %}
|
||||||
|
|
||||||
|
You can also control wether or not errors are displayed to the screen (good for development) or hidden, and logged
|
||||||
|
(good for production). For more information on this check out the [Error Reporting][errorreport] section.
|
||||||
|
|
||||||
|
### Inline Error Supression
|
||||||
|
|
||||||
|
As well as setting the level of error reporting during script execution you can also suppress specific errors from being
|
||||||
|
displayed using the Error Control Operator `@`. You simply put this operator at the beginning an expression, and any
|
||||||
|
error that would be caused as a direct result of the specific expression will be silenced.
|
||||||
|
|
||||||
|
{% highlight php %}
|
||||||
|
echo @$foo['bar'];
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
This will output `$foo['bar']` if it exists, but will simply return a null and print nothing if the variable `$foo` or
|
||||||
|
`'bar'` key does not exist.
|
||||||
|
|
||||||
|
This might seem like a good idea, but due to the way PHP actually handles `@` it is incredibly unperformant, and has the
|
||||||
|
unexpected effect of still actually logging the error anyway. If you have this code in a loop that runs 100 times in an
|
||||||
|
instance, and you run that 1 million times, then you've got 100 million lines in your logs.
|
||||||
|
|
||||||
|
Instead, use the following:
|
||||||
|
|
||||||
|
{% highlight php %}
|
||||||
|
echo isset($foo['bar']) ? $foo['bar'] : '';
|
||||||
|
{% endhighlight %}
|
||||||
|
|
||||||
|
This will be much quicker, and save filling up your logs with junk. [SitePoint] go a step further and say you should
|
||||||
|
[never suppress notices] with `@`.
|
||||||
|
|
||||||
|
One instance where error suppression might make sense is where `fopen()` fails to find a file to load. You could check
|
||||||
|
for existence of the file before you try to load it, but if the file is deleted after the check and before the `fopen()`
|
||||||
|
(which might sound impossible, but it can happen) then `fopen()` will return false _and_ throw an error. This is
|
||||||
|
potentially something PHP should resolve, but is one case where error suppression might seem like the only valid
|
||||||
|
solution.
|
||||||
|
|
||||||
* [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php)
|
* [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php)
|
||||||
|
* [SitePoint](http://www.sitepoint.com/)
|
||||||
|
* [never suppress notices](http://www.sitepoint.com/why-suppressing-notices-is-wrong/)
|
||||||
|
|
||||||
### Error Exceptions
|
### ErrorException's
|
||||||
|
|
||||||
Optionally you can throw your Errors as Exceptions using the `ErrorException` class, this class extends the `Exception`
|
PHP is perfectly capable of being an "exception-heavy" programming language, and only requires a few lines of code to
|
||||||
class. This is a common practice and by passing errors off as Exceptions in development you can handle them better than
|
make the switch. Basically you can throw your "errors" as "exceptions" using the `ErrorException` class, which extends the `Exception` class.
|
||||||
the usual result. By passing these Errors as Exceptions and not trying to catch them in Development the hope is that
|
|
||||||
you'll catch the Error and hopefully this will allow you to deal with the issue before it becomes a problem in a
|
This is a common practice implemented by a large number of modern frameworks such as Symfony and Laravel. By default
|
||||||
Production Environment.
|
Laravel will display all errors as exceptions using the [Whoops!] package if the `app.debug` switch is turned on, then
|
||||||
More information on this and details on how to use `ErrorException` with Error Handling can be found at
|
hide them if the switch is turned off.
|
||||||
|
|
||||||
|
By throwing errors as exceptions in development you can handle them better than the usual result, and if you see an
|
||||||
|
exception during development you can wrap it in a catch statement with specific instructions on how to handle the situation. Each exception you catch instantly makes your application that little bit more robust.
|
||||||
|
|
||||||
|
More information on this and details on how to use `ErrorException` with error handling can be found at
|
||||||
[ErrorException Class][errorexception].
|
[ErrorException Class][errorexception].
|
||||||
|
|
||||||
* [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php)
|
* [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php)
|
||||||
* [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php)
|
* [Predefined Constants for Error Handling](http://www.php.net/manual/en/errorfunc.constants.php)
|
||||||
* [error_reporting](http://www.php.net/manual/en/function.error-reporting.php)
|
* [error_reporting](http://www.php.net/manual/en/function.error-reporting.php)
|
||||||
* [ErrorException Class][errorexception]
|
|
||||||
* [Reporting][errorreport]
|
* [Reporting][errorreport]
|
||||||
|
|
||||||
[errorexception]: http://php.net/manual/en/class.errorexception.php
|
[errorexception]: http://php.net/manual/en/class.errorexception.php
|
||||||
[errorreport]: /#error_reporting
|
[errorreport]: /#error_reporting
|
||||||
|
[Whoops!]: http://filp.github.io/whoops/
|
||||||
|
Reference in New Issue
Block a user