Wednesday, 11 July 2018

PHP Finally In Try-Catch Block Tutorial

PHP Finally In Try-Catch Block Tutorial

OverView

An exception is a logical or system error that disrupt the normal execution of the script.Exception handling is one of the powerful mechanism to handle exceptions.It uses try catch block to trap exceptions.It is introduced in PHP since version 5.Introduction of Finally block in exceptional handling makes it more powerful.
  • Definition

       The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling- It is used to perform cleanup code such as closing a file ,closing a database connection etc.
finally

Syntax

1
2
3
4
5
6
7
8
<br />
try {<br />
      //do something<br />
} catch(Exception ex) {<br />
     //handle an error<br />
} finally {<br />
    //clean up after yourself<br />
}<br />
Lets understand the syntax with the help of an example
1
2
3
4
5
6
7
8
9
10
11
12
<br />
&lt;?php<br />
 try {<br />
     echo &quot;this is our try block\n&quot;;<br />
     echo &quot;it will throw an exception\n&quot;;<br />
     echo &quot;which will be caught by catch block\n&quot;;<br />
     throw new Exception();<br />
} catch (Exception $e) {<br />
     echo &quot;something went wrong\n&quot;;<br />
} finally {<br />
     echo &quot;This part is always executed\n&quot;;<br />
}<br />
Output:
this is our try block
it will throw an exception
which will be caught by catch block
something went wrong
This part is always executed
Whether an exception is thrown or not, the code inside the finally block would definitely execute.

Usage

  • In the finally block we usually have code that is used to perform cleanup activities corresponding to the code in the try block. When an exception occurs in the try block control comes to the catch block and the rest of the code in the try block would not execute. In such cases we may need to have some code that cleans up the objects that we created/used in the try block.
Let’s understand it with the example given below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<br />
&lt;?php<br />
     try {<br />
          $con=new mysqli(&quot;localhost&quot;,&quot;root&quot;,&quot;abc123&quot;,&quot;PersonsDetail&quot;);<br />
          if ($con-&gt;connect_errno) {<br />
              throw new Exception($con-&gt;connect_error);<br />
          }<br />
          $result = mysqli_query($con,&quot;SELECT * FROM Persons&quot;);<br />
          if($con-&gt;error){<br />
           throw new Exception($con-&gt;error);<br />
      }<br />
      while($row = mysqli_fetch_array($result)) {<br />
          echo $row['FirstName'] . &quot; &quot; . $row['LastName'];<br />
          echo &quot;&lt;br&gt;&quot;;<br />
      }<br />
     }catch (Exception $e){<br />
        echo $e-&gt;getMessage();<br />
     }<br />
     finally {<br />
    $con-&gt;close();<br />
        echo 'Now connection is closed!';<br />
     }<br />
?&gt;<br />
In case of an error, the mysql connection would remain open if we do not have the finally block.
Example 2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<br />
&lt;?php<br />
  error_reporting(E_ALL);<br />
  ini_set('display_errors', 1);<br />
  function checkNum($number) {<br />
      try {<br />
         echo &quot;Try block started\n&quot;;<br />
         $marks=array(100,99,98,76);<br />
     $arrayLength=sizeof($marks);<br />
         if($number&gt;$arrayLength){<br />
             throw new OutOfRangeException(&quot;illegal index is requested!&quot;);<br />
     }else{<br />
         return $marks[$number];<br />
     }<br />
      } catch (RuntimeException $e) {<br />
         echo &quot;Inner Exception: &quot; . $e-&gt;getMessage() . &quot;\n&quot;;<br />
      } finally {<br />
         print &quot;finally under Parent!\n&quot;;<br />
      }<br />
  }</p>
<p>  try {<br />
      $value=checkNum(5);<br />
      echo $value;<br />
  } catch (Exception $e) {<br />
      echo &quot;Outer Exception: &quot; . $e-&gt;getMessage() . &quot;\n&quot;;<br />
  } finally {<br />
      echo &quot;Outer Finally\n&quot;;<br />
  }<br />
?&gt;<br />
Output:
Try block started
finally under Parent!
Outer Exception: illegal index is requested!
Outer Finally
In the above Example, 5 is passed as an argument to the function checkNum.this function,checks whether the passed argument is less than array length or not.If it is not,then OutOfRangeException is thrown.But there is no catch block for this type of exception in the child try-catch-finally block.Now this exception is handled by the parent try-catch-finally block.If there is no exception handler at this level then Fatal error is thrown by the PHP. Above given output shows finally block executes irrespective of exception handling.So It is useful to cleanup the child objects and parent object used in the child try-catch-finally block and parent try-catch-finally block respectively.
  • One more powerful thing of exceptional handling is finally block executes first   and then return from try-catch block.If a function is returning something and that function using try-catch-finally block,then it will  postpone the return and execute the finally block first.
  • See this in the example given below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<br />
&lt;?php<br />
     error_reporting(E_ALL);<br />
     ini_set('display_errors', 1);<br />
     function getpersonDetails($id){<br />
         try {<br />
              $con=new mysqli(&quot;localhost&quot;,&quot;root&quot;,&quot;abc123&quot;,&quot;personsDetail&quot;);<br />
          if ($con-&gt;connect_errno) {<br />
                  throw new Exception($con-&gt;connect_error);<br />
          }<br />
          $sql=&quot;SELECT * FROM Details Where person_id=&quot;.$id;<br />
          $result = mysqli_query($con,$sql);<br />
          if($con-&gt;error){<br />
         throw new Exception($con-&gt;error);<br />
          }<br />
          return $result;<br />
     } catch (Exception $e) {<br />
              echo $e-&gt;getMessage();<br />
         }<br />
         finally {<br />
        $con-&gt;close();<br />
            echo 'Now connection is closed!';<br />
         }<br />
     }</p>
<p>     try {<br />
          $result=getpersonDetails(1);<br />
          while($row = mysqli_fetch_array($result)) {<br />
         echo $row['full_name'] . &quot; &quot; . $row['age'];<br />
         echo &quot;&lt;br&gt;&quot;;<br />
      }<br />
     } catch (Exception $e) {<br />
          echo &quot;Outer Exception: &quot; . $e-&gt;getMessage() . &quot;\n&quot;;<br />
     } finally {<br />
          echo &quot;Outer Finally\n&quot;;<br />
     }<br />
?&gt;<br />
Output:
Now connection is closed!
Anil Kumar 29
Outer Finally
  • Be aware of these three rules mentioned below, while using the return statement in the function using try-catch-finally block.
  1. Any return statement inside the try-catch block will be overridden by finally block.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<br />
&lt;?php<br />
function getLuckyName() {<br />
  try {<br />
     throw new Exception();<br />
     $name=&quot;Shah Rukh Khan&quot;;<br />
     return $name;<br />
  } catch (Exception $e) {<br />
     print &quot;Exception! Says villan\n&quot;;<br />
     $name=&quot;Prem Chopra&quot;;<br />
     return $name;<br />
  } finally {<br />
     print &quot;But Finally your lucky name is:-\n&quot;;<br />
     $name=&quot;Amitabh Bachchan&quot;;<br />
     return $name;<br />
  }<br />
  $name=&quot;Akshay Kumar&quot;;<br />
  return $name;<br />
}<br />
$luckyName=getLuckyName();<br />
echo $luckyName;<br />
?&gt;<br />
Output:
Exception! Says villan
But, Finally your lucky name is:-
Amitabh Bachchan
2)The exception not caught by the current try-catch-finally block, will not be reraised to the parent while returning value from the try-catch-finally block.
3)   As we Know that the return values of try-catch block can be overwritten by the return value of finally block,even then the postponed return statement can be evaluated beforehand.
The example given below help you understand these rules:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<br />
&lt;?php<br />
    function lockResource() {<br />
       print &quot;All the resources locked\n&quot;;<br />
       return &quot;locked&quot;;<br />
    }<br />
    function error() {<br />
        print &quot;Exception!Locked resources contain errors\n&quot;;<br />
        return &quot;error&quot;;<br />
    }<br />
    function unlockResource() {<br />
        print &quot;Finally!Unlock the locked resources\n&quot;;<br />
        return &quot;unlocked&quot;;<br />
    }</p>
<p>    function getResources() {<br />
        try {<br />
             throw new Exception();<br />
             return lockResource();<br />
        } catch (Exception $e) {<br />
             return error();<br />
        } finally {<br />
             return unlockResource();<br />
        }<br />
        return &quot;getResource&quot;;<br />
    }<br />
    print getResources() . &quot;\n&quot;;<br />
?&gt;<br />
Output:
Exception!Locked resources contain errors
Finally!Unlock the locked resources
unlocked
In the above example,When an exception is thrown it is caught by the catch block,where it’s called the error(),it  has return statement which is overridden by the return statement of the finally block. finally block returns the thing which is returned by the  function unlockResource().
Conclusion:
The finally block is a key tool for preventing resource leaks. When closing a file or otherwise recovering resources, place the code in a finally block to ensure that resource is always recovered.The finally block will not be executed if program exits(either by calling exit() ,die() or by causing a fatal error that causes the process to abort).

0 comments:

Post a Comment