Try catch trong PHP

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.

Try catch trong PHP

Xử lý ngoại lệ trong PHP – PHP Exceptions

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

Ví dụ:

 Before try block"; 
    try { 
        echo "
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 "
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 "
Exception Caught: ", $e->getMessage(); } // This line will be executed whether // Exception has been thrown or not echo "
After catch (will be always executed)"; } // Exception will not be rised demo(2); echo '
'; echo '
'; // 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:

 Before try block";
    try {
        echo "
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 "
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 "
Exception Caught: ", $e->getMessage(); echo "
Exception Caught: ", $e->getFile(); echo "
Exception Caught: ", $e->getCode(); echo "
Exception Caught: ", $e->getLine(); echo "
Exception Caught: ", $e->getTraceAsString(); } // This line will be executed whether // Exception has been thrown or not echo "
After catch (will be always executed)"; } // Exception will not be rised demo(5); echo '
'; echo '
'; // 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.

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ả:

 Before try block"; 
    try { 
        echo "
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 "
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 "
Exception Caught: ", $e->getMessage(); } // This line will be executed whether // Exception has been thrown or not echo "
After catch (will be always executed)"; } // Exception will not be rised demo(2); echo '
'; echo '
'; // Exception will be rised here demo(0); ?>
2

Đầ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ụ:

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.

Exception: " . $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:

 Before try block"; 
    try { 
        echo "
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 "
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 "
Exception Caught: ", $e->getMessage(); } // This line will be executed whether // Exception has been thrown or not echo "
After catch (will be always executed)"; } // Exception will not be rised demo(2); echo '
'; echo '
'; // Exception will be rised here demo(0); ?>
0
 Before try block"; 
    try { 
        echo "
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 "
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 "
Exception Caught: ", $e->getMessage(); } // This line will be executed whether // Exception has been thrown or not echo "
After catch (will be always executed)"; } // Exception will not be rised demo(2); echo '
'; echo '
'; // Exception will be rised here demo(0); ?>
1

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!

Nếu các bạn cảm thấy Website TanHongIT.Com thật sự hữu ích mình mong các bạn có thể chia sẻ những bài viết đến cho cộng đồng cùng thao khảo nhé. Cảm ơn các bạn !!!

Các bạn có bất kì thắc mắc cần được hỗ trợ hay yêu cầu các phần mềm, thủ thuật, khoá học,… thì cứ để lại comment bên dưới bài viết hoặc liên hệ qua fanpage của TanHongIT để được hỗ trợ nhé! Mình sẽ cố gắng chia sẻ cho các bạn mọi thứ cần thiết nhất!