Nov 14, 2011

Exception handling in PHP

What is an exception?
An exception is an event that occurs during the execution of a program and requires controlled execution of a block of code outside the normal flow of execution

Exception handling is a very powerful tool when performing a management situation. The first thing to understand is that an exception is not an error. It's a situation that is experienced and a block of code that can not handle.

Why should I use?
Proper exception handling can make your code more reliable save you headaches.

When I throw an exception when an error?
Depends somewhat on the politics of project you're working on, and tastes of each developer. As with the names of the variables, it is best to arrive at a sort of standard within each team.

In general, if we are working on a senior class of an application and very attached to it, the best option may be to report the error using the error handling of the application itself, and try to control it in this place.

If instead we are working on a class of low-level, decoupled from the application you are working and capable of being reused, it is best to throw an exception and let the class try to capture up to inform the user.

How to throw an exception?
An exception is thrown through the reserved word Thrown, we see an example.


<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php function foo(){ throw new Exception (' Upps !!'); } foo(); // PHP Fatal error: Uncaught exception 'Exception' with message ' Upps !!'</span> <? Php function foo () {throw new Exception ('Upps !!');} foo () / / PHP Fatal error: Uncaught exception' Exception 'with message' Upps! '</span>
So what?
When an exception is thrown PHP try to find a catch {} block capable of capturing, if none are found then the execution will stop and issue a PHP fatal error with the message "Uncaught Exception ...".

To "capture" an exception code must be within a try {} and must have at least one catch {} block. Here is an example.


<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function foo() {</span> function foo () {</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">try {</span> try {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">throw new Exception(' Upps !!');</span> throw new Exception ('Upps !!');</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} catch (Exception $e) {</span> } Catch (Exception $ e) {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">// ..</span> / / ..</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">foo();</span> foo ();</span>
In this second example the program execution is not interrupted even though it has launched an exception.

Here's another example with multiple catch blocks

<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function foo() {</span> function foo () {</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">try {</span> try {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">throw new Exception(' Upps !!');</span> throw new Exception ('Upps !!');</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} catch (ErrorException $e) {</span> } Catch (ErrorException $ e) {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">// este bloque no se ejecuta, no coincide el tipo de excepción</span> / / This block is not executed, does not match the type of exception</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">echo 'ErrorException' .</span> echo 'ErrorException'.</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">$e->getMessage();</span> $ E-> getMessage ();</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} catch (Exception $e) {</span> } Catch (Exception $ e) {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">// este bloque captura la excepción</span> / / This block catches the exception</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">echo 'Exception' .</span> echo 'Exception'.</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">$e->getMessage();</span> $ E-> getMessage ();</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">foo();</span> foo ();</span>
Methods of an exception.
An exception is an object after all, then the methods we have available:

getMessage () returns the exeption message.
getCode () returns the error code.
getFile () returns the name of the file that threw the exception.
getLine () returns the line of the file that threw the exception.
getTrace () returns the cell array format ejeción.
getTraceAsString () returns the stack ejeción format string.
You can find the complete reference on php official site.

Exception Handling
Thanks to set_exception_handler () can handle exceptions not caught by try / cacth.

Thanks to this feature of PHP, you can set to do when an exception occurs, such as:

Generate a log.
Show an error message in a controlled manner.
Send complete information to system administrators so they can debug it.
Here is an example for set_exception_handler:

<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/*</span> / *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* recupera información de la</span> * Retrieves information from the</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* maquina en la que se está efecutando</span> * Machine on which it is efecutando</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @return string $info</span> * @ Return string $ info</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function getInfoMachine() { /* ...</span> getInfoMachine function () {/ * ...</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/*</span> / *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* recupera información de la</span> * Retrieves information from the</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* variables, $_POST, $_GET, $_SESSION</span> * Variables, $ _POST, $ _GET, $ _SESSION</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @return string $info</span> * @ Return string $ info</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function getInfoEnviroment() { /* ...</span> getInfoEnviroment function () {/ * ...</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/*</span> / *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* recupera información del usuario que</span> * Retrieves user information</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* esta ejecutando el proceso, en una aplicación</span> * Process is running in an application</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* con gestión de usuarios.</span> * With user management.</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @return string $info</span> * @ Return string $ info</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function getInfoUser() { /* ...</span> getInfoUser function () {/ * ...</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/*</span> / *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* recupera información de la excepción</span> * Retrieves exception information</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @param Exception $e</span> * @ Param Exception $ e</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @return string $info</span> * @ Return string $ info</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function getInfoException(Exception $e) { /* ...</span> getInfoException function (Exception $ e) {/ * ...</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/*</span> / *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* envia informacion a los administradores del sistema</span> * Send information to system administrators</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*</span> *</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @param Exception $e</span> * @ Param Exception $ e</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">* @return true or false</span> * @ Return true or false</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/</span> * /</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function exception_handle(Excepion $e) {</span> exception_handle function (Excepion $ e) {</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">$text = getInfoMachine() .</span> $ Text = getInfoMachine ().</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">getInfoEnviroment() .</span> getInfoEnviroment ().</span>            <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">getInfoUser() .</span> getInfoUser ().</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">getInfoException($e);</span> getInfoException ($ e);</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">mail($admins, $e->getMessage(), $message);</span> mail ($ admins, $ e-> getMessage (), $ message);</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">set_exception_handler('exception_handler');</span> set_exception_handler ('exception_handler');</span>
Creating your own exceptions
Why would we want to create a new type of expceción? Very easy to contemplate specific situations, for example if I am making a library that performs image processing, I can want to add extra information to the exception concerning the processing of images.


<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">class MyException extends Exception {/* ...</span> MyException class extends Exception {/ * ...</span> <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">*/}</span> * /}</span>
Cases PROFESSIONALS
The following are some cases that we know PROFESSIONALS.

Errors
A typical error when dealing with exceptions, and no experience, is to skip blocks of code that needed to catch exceptions, we see an example.

<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function foo() {</span> function foo () {</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('LOCK TABLES `a`, `b` WRITE');</span> DB:: query ('LOCK TABLES `a`, `b` WRITE');</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">try {</span> try {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* operaciones SQL */</span> / * SQL operations * /</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} catch (Exception $e) {</span> } Catch (Exception $ e) {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* operaciones SQL */</span> / * SQL operations * /</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('UNLOCK TABLES');</span> DB:: query ('UNLOCK TABLES');</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
In this example we see how the code that unlocks the tables, is outside the catch block, so if an exception occurs the tables will be blocked. Therefore, the catch code must deal with free tables.

<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function foo() {</span> function foo () {</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('LOCK TABLES `a`, `b` WRITE');</span> DB:: query ('LOCK TABLES `a`, `b` WRITE');</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">try {</span> try {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* operaciones SQL */</span> / * SQL operations * /</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} catch (Exception $e) {</span> } Catch (Exception $ e) {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* operaciones SQL */</span> / * SQL operations * /</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('UNLOCK TABLES');</span> DB:: query ('UNLOCK TABLES');</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('UNLOCK TABLES');</span> DB:: query ('UNLOCK TABLES');</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>
Reviving an exception.
In some situations I can will relaunch an exception, if for example I want to execute a block of code to occur, but the upper classes delegate ultimate control of it. Using the same example of the previous block.

<span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">< ?php</span> <? Php</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">function foo() {</span> function foo () {</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('LOCK TABLES `a`, `b` WRITE');</span> DB:: query ('LOCK TABLES `a`, `b` WRITE');</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">try {</span> try {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* operaciones SQL */</span> / * SQL operations * /</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">} catch (Exception $e) {</span> } Catch (Exception $ e) {</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">/* operaciones SQL */</span> / * SQL operations * /</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('UNLOCK TABLES');</span> DB:: query ('UNLOCK TABLES');</span>        <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">throw $e;</span> throw $ e;</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>    <span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">DB::query('UNLOCK TABLES');</span> DB:: query ('UNLOCK TABLES');</span><span onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span>

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Premium Wordpress Themes