PHP Cơ bản
PHP Nâng cao
PHP & Cơ sở dữ liệu MySQL
Ví dụ PHP
Tài liệu tham khảo PHP
Quảng cáo

Xử lý ngoại lệ trong PHP

Trong hướng dẫn này, bạn sẽ học cách đưa ra (throw) và nắm bắt (catch) các ngoại lệ trong PHP.

Ngoại lệ trong PHP là gì?

Một ngoại lệ là một tín hiệu cho biết một số loại sự kiện hoặc lỗi đặc biệt đã xảy ra. Các trường hợp ngoại lệ có thể xảy ra do nhiều lý do khác nhau, chẳng hạn như kết nối cơ sở dữ liệu hoặc truy vấn không thành công, tệp bạn đang cố gắng truy cập không tồn tại, v.v.

PHP cung cấp một cơ chế xử lý ngoại lệ mạnh mẽ cho phép bạn xử lý các ngoại lệ một cách duyên dáng. Trái ngược với hệ thống xử lý lỗi truyền thống của 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 được kiểm soát và linh hoạt hơn. Mô hình ngoại lệ lần đầu tiên được giới thiệu trong PHP 5.

Cách sử dụng câu lệnh Throw và Try ... Catch

Trong cách tiếp cận dựa trên ngoại lệ, mã chương trình được viết trong một khối try, một ngoại lệ có thể được đưa ra bằng cách sử dụng câu lệnh throw khi một sự kiện ngoại lệ xảy ra trong quá trình thực thi mã trong một khối try. Sau đó, nó được bắt và giải quyết bởi một hoặc nhiều khối catch.

Ví dụ sau minh họa cách xử lý ngoại lệ hoạt động:

Ví dụ

<?php
function division($dividend, $divisor){
    // Throw exception if divisor is zero
    if($divisor == 0){
        throw new Exception('Division by zero.');
    } else{
        $quotient = $dividend / $divisor;
        echo "<p>$dividend / $divisor = $quotient</p>";
    }
}
 
try{
    division(10, 2);
    division(30, -4);
    division(15, 0);
    
    // If exception is thrown following line won't execute
    echo '<p>All divisions performed successfully.</p>';
} catch(Exception $e){
    // Handle the exception
    echo "<p>Caught exception: " . $e->getMessage() . "</p>";
}
 
// Continue execution
echo "<p>Hello World!</p>";
?>

Bạn có thể tự hỏi mã này là gì. Nào, chúng ta hãy lần lượt xem qua từng phần của đoạn mã này để hiểu rõ hơn.

Giải thích mã

Hệ thống xử lý ngoại lệ của PHP có bốn phần cơ bản: try, throw, catch, và lớp ngoại lệ (Exception). Danh sách sau đây mô tả cách hoạt động chính xác của từng bộ phận.

  • Hàm division() trong ví dụ trên sẽ kiểm tra nếu một ước là bằng không. Nếu đúng như vậy, một ngoại lệ sẽ được đưa ra thông qua câu lệnh throw của PHP . Nếu không, hàm này thực hiện phép chia bằng các số đã cho và hiển thị kết quả.
  • Sau đó, hàm division() được gọi trong một khối try với các đối số khác nhau. Nếu một ngoại lệ được tạo ra trong khi thực thi mã trong khối try, PHP sẽ dừng thực thi tại thời điểm đó và cố gắng tìm khối catch tương ứng . Nếu nó được tìm thấy, mã trong khối catch đó sẽ được thực thi, nếu không, một lỗi nghiêm trọng sẽ được tạo ra (fatal error).
  • Các khối catch thường bắt ngoại lệ được đưa ra trong khối try và tạo ra một đối tượng ($e) chứa các thông tin ngoại lệ. Thông báo lỗi từ đối tượng này có thể được truy xuất bằng phương thức getMessage() của Exception .

Lớp ngoại lệ của PHP cũng cung cấp phương thức getCode(), getFile(), getLine()getTraceAsString() có thể được sử dụng để tạo ra thông tin gỡ lỗi chi tiết.

Ví dụ

<?php
// Turn off default error reporting
error_reporting(0);
 
try{
    $file = "somefile.txt";
    
    // Attempt to open the file
    $handle = fopen($file, "r");
    if(!$handle){
        throw new Exception("Cannot open the file!", 5);
    }
    
    // Attempt to read the file contents
    $content = fread($handle, filesize($file));
    if(!$content){
        throw new Exception("Could not read file!", 10);
    }
    
    // Closing the file handle
    fclose($handle);
    
    // Display file contents
    echo $content;
} catch(Exception $e){
    echo "<h3>Caught Exception!</h3>";
    echo "<p>Error message: " . $e->getMessage() . "</p>";    
    echo "<p>File: " . $e->getFile() . "</p>";
    echo "<p>Line: " . $e->getLine() . "</p>";
    echo "<p>Error code: " . $e->getCode() . "</p>";
    echo "<p>Trace: " . $e->getTraceAsString() . "</p>";
}
?>

Phương thức khởi tạo của Exception tùy ý nhận một thông báo ngoại lệ và một mã ngoại lệ. Mặc dù thông báo ngoại lệ thường được sử dụng để hiển thị thông tin chung về những gì đã xảy ra, mã ngoại lệ có thể được sử dụng để phân loại lỗi. Mã ngoại lệ được cung cấp có thể được truy xuất sau đó thông qua phương thức getCode() của Exception .

Mẹo: Ngoại lệ chỉ nên được sử dụng để biểu thị các điều kiện ngoại lệ; chúng không nên được sử dụng để kiểm soát luồng ứng dụng bình thường, ví dụ: nhảy đến một vị trí khác trong tập lệnh tại một điểm cụ thể. Làm điều đó sẽ ảnh hưởng xấu đến hiệu suất ứng dụng của bạn.

Xác định ngoại lệ tùy chỉnh

Bạn thậm chí có thể xác định các trình xử lý ngoại lệ tùy chỉnh của riêng mình để xử lý các loại ngoại lệ khác nhau theo một cách khác. Nó cho phép bạn sử dụng một khối catch riêng biệt cho từng loại ngoại lệ.

Bạn có thể xác định một ngoại lệ tùy chỉnh bằng cách mở rộng lớp Ngoại lệ, vì Ngoại lệ là lớp cơ sở cho tất cả các ngoại lệ. Lớp ngoại lệ tùy chỉnh kế thừa tất cả các thuộc tính và phương thức từ lớp Ngoại lệ của PHP. Bạn cũng có thể thêm các phương thức tùy chỉnh của mình vào lớp ngoại lệ tùy chỉnh. Hãy xem ví dụ sau:

Ví dụ

<?php
// Extending the Exception class
class EmptyEmailException extends Exception {}
class InvalidEmailException extends Exception {}
 
$email = "someuser@example..com";
 
try{
    // Throw exception if email is empty
    if($email == ""){
        throw new EmptyEmailException("<p>Please enter your E-mail address!</p>");
    }
    
    // Throw exception if email is not valid
    if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {           
        throw new InvalidEmailException("<p><b>$email</b> is not a valid E-mail address!</p>");
    }
    
    // Display success message if email is valid
    echo "<p>SUCCESS: Email validation successful.</p>";
} catch(EmptyEmailException $e){
    echo $e->getMessage();
} catch(InvalidEmailException $e){
    echo $e->getMessage();
}
?>

Trong ví dụ trên, chúng ta đã dẫn xuất hai lớp ngoại lệ mới: EmptyEmailException InvalidEmailException từ lớp cơ sở Exception. Nhiều khối catch được sử dụng để hiển thị các thông báo lỗi khác nhau, tùy thuộc vào loại ngoại lệ được tạo ra.

Kể từ khi các lớp ngoại lệ tùy chỉnh kế thừa các thuộc tính và phương pháp từ lớp Exception, vì vậy chúng ta có thể sử dụng phương thức của lớp ngoại lệ như getMessage(), getLine(), getFile(), vv để lấy thông tin lỗi từ đối tượng ngoại lệ.

Đặt một Trình xử lý Ngoại lệ Toàn cầu

Như chúng ta đã thảo luận trước đó trong chương này nếu không bắt được ngoại lệ, PHP sẽ tạo ra Lỗi nghiêm trọng với thông báo "Uncaught Exception ...". Thông báo lỗi này có thể chứa thông tin nhạy cảm như tên tệp và số dòng nơi sự cố xảy ra. Nếu bạn không muốn để lộ thông tin như vậy cho người dùng, bạn có thể tạo một hàm tùy chỉnh và đăng ký nó với hàm set_exception_handler() để xử lý tất cả các trường hợp ngoại lệ không cần thiết.

Ví dụ

<?php
function handleUncaughtException($e){
    // Display generic error message to the user
    echo "Opps! Something went wrong. Please try again, or contact us if the problem persists.";
    
    // Construct the error string
    $error = "Uncaught Exception: " . $message = date("Y-m-d H:i:s - ");
    $error .= $e->getMessage() . " in file " . $e->getFile() . " on line " . $e->getLine() . "\n";
    
    // Log details of error in a file
    error_log($error, 3, "var/log/exceptionLog.log");
}
 
// Register custom exception handler
set_exception_handler("handleUncaughtException");
 
// Throw an exception
throw new Exception("Testing Exception!");
?>

Ghi chú: Một ngoại lệ không cần thiết sẽ luôn dẫn đến việc kết thúc tập lệnh. Vì vậy, nếu bạn muốn tập lệnh tiếp tục thực thi sau thời điểm xảy ra ngoại lệ, bạn phải có ít nhất một khối catch tương ứng cho mỗi khối try.

Bài viết này đã giúp ích cho bạn?

Advertisements