Ngoại lệ, error và xử lý ngoại lệ là những khái nhiệm rất quen thuộc đối với tất cả các lập trình viên. Bài viết này trình bày các vấn đề liên quan đến Exception trong PHP. PHP có cung cấp các cơ chế giúp bắt lỗi, giám sát các lỗi và xử lý các lỗi có thể xảy ra khi lập trình.
Trong nhiều ứng dụng lớn, có thể mở rộng, trong các ứng dụng hướng đối tượng và các frameworks thì việc bắt được các Exception trong quá trình develop là điều cực kì tốt.

Ngoại lệ (Exception) trong PHP là gì?
Bạn có thể hiểu nôm na ngoại lệ như sau: Trong lập trình chúng ta sẽ tạo ra những đoạn code, hàm, mảng mới mong muốn nó thực hiện một hành động nào đó trong chương trình. Như vậy, tất cả các hành động có thể xảy ra mà khác với mong muốn đó thì nó chính là ngoại lệ (Exception).
Và chúng ta sẽ không bao giờ muốn cho chương trình của mình hoạt động sai mong muốn phải không nào. Vì thế mà ta cần xử lý ngoại lệ để tránh những ngoại lệ đó phá hỏng chương trình.
Trái ngược với hệ thống xử lý lỗi trong PHP, xử lý ngoại lệ là phương pháp hướng đối tượng để xử lý lỗi, cung cấp hình thức báo cáo lỗi linh hoạt và có kiểm soát hơn.
Các phương pháp xử lý ngoại lệ trong PHP
- Sử dụng try, throw và catch.
- Tạo lớp ngoại lệ tùy chỉnh.
- Xử lý nhiều ngoại lệ.
- Ném lại một ngoại lệ.
- Thiết lập trình xử lý ngoại lệ cao cấp.
Xử lý ngoại lệ (Exception Handling) trong PHP
Sử dụng try, throw và catch
Ta sẽ có một số khái niệm cần lưu ý dưới đây:
Try − Một hàm sử dụng một exception nên nằm trong khối try. Nếu exception không xảy ra( không được kích hoạt), code sẽ tiếp tục như bình thường. Tuy nhiên, nếu exception xảy ra ( được kích hoạt) thì exception đó sẽ bị “thrown”.
Throw − Đây là cách bạn kích hoạt một exception. Mỗi “thrown” phải có ít nhất một “catch”.
Catch − Mỗi khối “catch” bắt một exception và tạo một đối tượng chứa thông tin của exception đó.
Cú pháp tổng quát của try catch
<?php try { //Thực hiện đoạn mã này có khả năng ném ra một ngoại lệ } catch (Exception $e) { //Xử lý ngoại lệ ở đây } ?>
Ví dụ:
<?php // PHP Program to illustrate normal // try catch block code function demo($var) { echo "<br> Before try block"; try { echo "<br> Inside try block"; // If var is zero then only if will be executed if($var == 0) { // If var is zero then only exception is thrown throw new Exception('Number is zero.'); // This line will never be executed echo "<br> After throw (It will never be executed)"; } } // Catch block will be executed only // When Exception has been thrown by try block catch(Exception $e) { echo "<br> Exception Caught: ", $e->getMessage(); } // This line will be executed whether // Exception has been thrown or not echo "<br> After catch (will be always executed)"; } // Exception will not be rised demo(2); echo '<br>'; echo '<br>'; // Exception will be rised here demo(0); ?>
Kết quả:
Before try block Inside try block After catch (will be always executed) Before try block Inside try block Exception Caught: Number is zero. After catch (will be always executed)
Trong đó Hàm demo() kiểm tra nếu một số có bằng 0 hay không. Nếu điều kiện đúng ngoại lệ được ném ra. Khối “catch” lấy ra ngoại lệ và tạo ra một đối tượng ($e) chứa thông tin ngoại lệ. Thông báo lỗi từ ngoại lệ được lặp lại bằng cách gọi $e->getMessage() từ đối tượng ngoại lệ.
Trong ví dụ trên, hàm $e->getMessage() được sử dụng để lấy error message. Không chỉ có mỗi một hàm đó, dưới đây là một số hàm có thể được sử dụng từ lớp Exception trong PHP.
Một số hàm lấy error message
- getMessage() − thông báo của exception
- getCode() − code của exception
- hàm getFile() − tên source file
- getLine() − source line
- getTrace() − n mảng của backtrace()
- hàm getTraceAsString() − chuỗi được định dạng của trace
- getClass() – class có exception
Từ ví dụ về try catch trên ta có thể thêm như sau:
<?php // PHP Program to illustrate normal // try catch block code function demo($var) { echo "<br> Before try block"; try { echo "<br> Inside try block"; // If var is zero then only if will be executed if ($var == 0) { // If var is zero then only exception is thrown throw new Exception('Number is zero.'); // This line will never be executed echo "<br> After throw (It will never be executed)"; } } // Catch block will be executed only // When Exception has been thrown by try block catch (Exception $e) { echo "<br> Exception Caught: ", $e->getMessage(); echo "<br> Exception Caught: ", $e->getFile(); echo "<br> Exception Caught: ", $e->getCode(); echo "<br> Exception Caught: ", $e->getLine(); echo "<br> Exception Caught: ", $e->getTraceAsString(); } // This line will be executed whether // Exception has been thrown or not echo "<br> After catch (will be always executed)"; } // Exception will not be rised demo(5); echo '<br>'; echo '<br>'; // Exception will be rised here demo(0);
Before try block Inside try block After catch (will be always executed) Before try block Inside try block Exception Caught: Number is zero. Exception Caught: C:\wamp64\www\webdemo\index2.php Exception Caught: 0 Exception Caught: 14 Exception Caught: #0 C:\wamp64\www\webdemo\index2.php(41): demo(0) #1 {main} After catch (will be always executed)
Tạo lớp ngoại lệ tuỳ chỉnh
Để tạo một trình xử lý ngoại lệ tùy chỉnh, bạn phải tạo một lớp đặc biệt với các hàm có thể được gọi khi một ngoại lệ xảy ra trong PHP. Lớp này phải được kế thừa lớp Exception.
<?php class myException extends Exception { function get_Message() { // Error message $errorMsg = 'Error on line '.$this->getLine(). ' in '.$this->getFile() .$this->getMessage().' is number zero'; return $errorMsg; } } function demo($a) { try { // Check if if($a == 0) { throw new myException($a); } } catch (myException $e) { // Display custom message echo $e->get_Message(); } } // This will not generate any exception demo(5); // It will cause an exception demo(0); ?>
Kết quả: Error on line 18 in C:\wamp64\www\webdemo\index2.php0 is number zero
Đầu tiên ta sẽ tạo một class có tên myException được kế thừa từ class Exception, như vậy, nó sẽ kế thừa tất cả các phương thức và thuộc tính từ lớp Exception.
Trong class trên sẽ tạo một hàm get_message để thông báo lỗi nếu một số truyền vào bằng 0.
Ra khỏi class, ta dựng một hàm demo() với nội dung bên trong thực hiện try catch để kiểm tra xem số truyền vào có bằng 0 không. Nếu số bằng 0, một ngoại lệ sẽ được ném và sau đó khối catch sẽ bắt được ngoại lệ về rồi hiển thị ra thông tin lỗi.
Xử lý nhiều ngoại lệ – Multiple Exceptions
Multiple Exceptions là cách sử dụng nhiều block try…catch để cố gắng bắt các ngoại lệ được ném ra.
Ở phương pháp này chúng ta có thể sử dụng các câu lệnh điều khiển như if…else, switch, hoặc các ngoại lệ lồng vào nhau.
Cú pháp tổng thể
try { // Some code... } catch (ExceptionType1 | ExceptionType2 $e) { // Code to handle the exception } catch (\Exception $e) { // ... }
Ví dụ:
<?php class A_Error extends Exception {} class B_Error extends Exception {} class C_Error extends Exception {} try { throw new A_Error(); } catch (A_Error $e) { goto abc; } catch (B_Error $e) { goto abc; } catch (C_Error $e) { abc: var_dump(get_class($e)); echo "Error one"; }
Xử lý nhiều ngoại lệ sẽ có ích khi bạn muốn hiển thị thông điệp hoặc thực hiện một hành động nào đó tuỳ thuộc vào mỗi ngoại lệ được ném ra.
Thiết lập xử lý ngoại lệ cao cấp – Set Top Level Exception Handler
Hàm set_exception_handler() sẽ đặt tất cả hàm do người dùng đã xác định thành tất cả ngoại lệ chưa được lưu.
<?php function myException($exception) { echo "<b>Exception:</b> " . $exception->getMessage(); } set_exception_handler('myException'); throw new Exception('Uncaught Exception occurred'); ?>
Trong đoạn mã trên không có khối “catch”. Thay vào đó, trình xử lý ngoại lệ cấp cao nhất được kích hoạt. Hàm này nên được sử dụng để bắt các ngoại lệ chưa được catch.
Kết quả:
Exception: Uncaught Exception occurred
Ví dụ khác:
<?php // PHP Program to illustrate normal // try catch block code // Function for Uncaught Exception function myException($exception) { // Details of Uncaught Exception echo "<br> Exception: " . $exception->getMessage(); } // Set Uncaught Exception handler set_exception_handler('myException'); function demo($var) { echo "<br> Before try block"; try { echo "<br> Inside try block"; // If var is zero then only if will be executed if($var == 0) { // If var is zero then only exception is thrown throw new Exception('Number is zero.'); // This line will never be executed echo "<br> After throw (It will never be executed)"; } } // Catch block will be executed only // When Exception has been thrown by try block catch(Exception $e) { echo "<br> Exception Caught: ", $e->getMessage(); } // This line will be executed whether // Exception has been thrown or not echo "<br> After catch (will be always executed)"; if($var < 0) { // Uncaught Exception throw new Exception('Uncaught Exception occurred'); } } // Exception will not be rised demo(2); echo '<br>'; // Exception will be rised here demo(0); // Uncaught Exception demo (-3); ?>
Before try block Inside try block After catch (will be always executed) Before try block Inside try block Exception Caught: Number is zero. After catch (will be always executed) Before try block Inside try block After catch (will be always executed) Exception: Uncaught Exception occurred
Tham khảo:
- https://www.php.net/manual/en/language.exceptions.php
- https://www.geeksforgeeks.org/exception-handling-in-php/
- https://stackoverflow.com/questions/8439581/catching-multiple-exception-types-in-one-catch-block/37522012
- https://github.com/php/php-src/commit/0aed2cc2a440e7be17552cc669d71fdd24d1204a
Kết thúc
Bài viết trên mình đã liệt kê một vài cách để xử lý ngoại lệ trong lập trình PHP. Mỗi bài viết về kiến thức học PHP của mình đều có thể chưa hoàn toàn đầy đủ, cho nên mong các bạn hãy tra google khi tham khảo và mong bạn có thể gửi lại comment bổ sung bên dưới để mình có thể hoàn thiện lại bài viết hơn. Cảm ơn các bạn!
Xem thêm:
- Bài 11: Các hàm xử lý mảng (Array) trong PHP
- 12: Chuỗi (String) Và Các Hàm Xử Lý Chuỗi Trong PHP
- Bài 13: Phương thức GET và POST trong PHP
- Bài 14: Cookie là gì? Cookie trong PHP
- 15: Session trong PHP
- Bài 16: Các hàm xử lý và làm việc với file trong PHP
- Bài 18: Những hàm kiểm tra dữ liệu trong PHP (isset, empty,…)
Tổng hợp Internet
CHÚC CÁC BẠN THÀNH CÔNG VÀ VUI VẺ