Bài 30: Xử lý lỗi trong PHP (PHP Error Handling)

“Hãy hòa nhã với những kẻ dở hơi. Ai biết được ngày sau bạn có thể phải làm việc cho một kẻ như vậy.”

Bill Gates

Microsoft

Trong bài hướng dẫn tự học PHP này, bạn sẽ học cách sử dụng các hàm xử lý lỗi trong PHP để xử lý khi xảy ra lỗi.

Lỗi là gì? Tại sao phải xử lý lỗi

Thỉnh thoảng ứng dụng hoặc trang web của bạn không chạy như mong muốn đó chính là lỗi. Có một số lý do gây ra lỗi ví dụ như sau:

  • Máy chủ có thể bị hết dung lượng / băng thông
  • Người dùng có thể đã nhập một giá trị không hợp lệ trong biểu mẫu
  • Bản ghi tệp hoặc cơ sở dữ liệu mà bạn đang cố truy cập có thể không còn tồn tại
  • Ứng dụng có thể không có quyền ghi vào một tệp trên đĩa
  • Một dịch vụ mà ứng dụng cần truy cập có thể tạm thời không khả dụng

Các loại lỗi này được gọi là runtime error (lỗi khi chạy), bởi vì chúng xảy ra tại thời điểm tập lệnh chạy. Chúng khác với các lỗi cú pháp cần được sửa trước khi chạy tập lệnh.

Lỗi là điều không mong muốn và gây khó chịu cho người dùng, thậm chí có thể gây hại cho ứng dụng.

Vì vậy, một trang web hay một ứng dụng chuyên nghiệp phải có khả năng xử lý lỗi thời gian chạy như vậy. Thông thường điều này có nghĩa là thông báo cho người dùng về vấn đề rõ ràng và chính xác hơn.

Hiểu rõ hơn về các cấp độ lỗi trong PHP

Thông thường, khi có sự cố ngăn tập lệnh chạy đúng, công cụ PHP sẽ gây ra lỗi. Mỗi lỗi được biểu thị bằng một giá trị nguyên và hằng số liên quan. Bảng sau liệt kê một số cấp độ lỗi phổ biến:

Cấp độ lỗiGiá trịMô tả
E_ERROR1Một lỗi Runtime nghiêm trọng, không thể được phục hồi. Việc thực thi kịch bản được dừng lại ngay lập tức
E_WARNING2Một cảnh báo runtime. Nó không trí mạng và hầu hết các lỗi có xu hướng rơi vào loại này. Việc thực thi kịch bản sẽ không dừng lại.
E_NOTICE8Một thông báo runtime. Cho biết rằng tập lệnh gặp phải lỗi có thể xảy ra, mặc dù tình huống cũng có thể xảy ra khi chạy tập lệnh bình thường
E_USER_ERROR256Một thông báo lỗi do người dùng tạo ra. Điều này giống như một E_ERROR, ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàm trigger_error () chứ không phải là PHP engine
E_USER_WARNING512Một thông điệp cảnh báo không trí mạng do người dùng tạo ra. Điều này giống như một E_WARNING, ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàm trigger_error () chứ không phải PHP engine
E_USER_NOTICE1024Một thông báo thông báo do người dùng tạo. Điều này giống như một E_NOTICE, ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàm trigger_error () chứ không phải PHP engine
E_STRIC2048Không hoàn toàn là một lỗi, nhưng được kích hoạt bất cứ khi nào PHP gặp mã có thể dẫn đến sự cố hoặc chuyển tiếp không tương thích
E_ALL8189Tất cả các lỗi và cảnh báo, ngoại trừ E_STRICT trước PHP 5.4.0.

Để tìm hiểu thêm, bạn có thể xem tại trang chủ của PHP tại đây

PHP Engine gây ra lỗi bất cứ khi nào nó gặp sự cố với tập lệnh của bạn, nhưng bạn cũng có thể tự kích hoạt lỗi để tạo ra nhiều thông báo lỗi thân thiện với người dùng hơn.

Bằng cách này bạn có thể làm cho ứng dụng của bạn trở nên thông minh hơn. Phần sau đây mô tả một số phương thức phổ biến được sử dụng để xử lý lỗi trong PHP

Xử lý lỗi trong PHP (PHP Error Handling)
Xử lý lỗi trong PHP (PHP Error Handling)

Xử lý lỗi cơ bản trong PHP với hàm die()

Hãy xem xét ví dụ sau, chúng ta chỉ đơn giản là cố gắng mở một tệp văn bản để chỉ đọc:

<?php
  // Cố gắng mở một tệp không tồn tại
  $file = fopen("sample.txt", "r");
?>

Nếu bạn cố gắng mở một tệp không tồn tại như ví dụ trên, bạn có thể gặp lỗi như thế này:

Warning: fopen(sample.txt) [function.fopen]: failed to open stream: No such file or directory in C:\wamp\www\project\test.php on line 2

Nếu chúng ta làm theo một số bước đơn giản, chúng ta có thể ngăn người dùng nhận được thông báo lỗi như vậy. Vì họ nhận thông báo như thế này cũng không hiểu, thậm chí gây khó chịu.

<?php
  if(file_exists("sample.txt")){
      $file = fopen("sample.txt", "r");
  } else{
      die("Error: File không tồn tại.");
  }
?>

Bây giờ nếu bạn chạy đoạn mã trên, bạn sẽ nhận được thông báo lỗi như thế này:

Error: File không tồn tại

Như bạn có thể thấy bằng cách thực hiện kiểm tra đơn giản xem tệp có tồn tại hay không trước khi thử truy cập nó, chúng ta có thể tạo thông báo lỗi có ý nghĩa hơn đối với người dùng.

Hàm die() được sử dụng ở trên chỉ đơn giản hiển thị thông báo lỗi tùy chỉnh và chấm dứt tập lệnh hiện tại nếu không tìm thấy tệp ‘sample.txt’

Hướng dẫn tạo trình xử lý lỗi tùy chỉnh trong PHP

Bạn có thể tạo chức năng xử lý lỗi của riêng mình để xử lý lỗi runtime do PHP Engine tạo ra.

Trình xử lý lỗi tùy chỉnh cung cấp cho bạn tính linh hoạt cao hơn và kiểm soát lỗi tốt hơn, nó có thể kiểm tra lỗi và quyết định phải làm gì với lỗi, nó có thể hiển thị thông báo cho người dùng, ghi lại lỗi trong tệp hoặc cơ sở dữ liệu hoặc gửi bởi e -mail, cố gắng khắc phục sự cố và tiếp tục, thoát khỏi việc thực thi tập lệnh hoặc bỏ qua lỗi hoàn toàn.

Hàm xử lý lỗi tùy chỉnh phải có khả năng xử lý ít nhất hai tham số (errno errstr), tuy nhiên, nó có thể tùy ý chấp nhận thêm ba tham số (errfile, errline errcontext), như được mô tả dưới đây:

Các tham số bắt buộc trong trình xử lý lỗi tùy chỉnh :

  • errno: Chỉ định mức độ lỗi, dưới dạng một số nguyên. Điều này tương ứng với hằng số cấp độ lỗi phù hợp (E_ERROR, E_WARNING, v.v.)
  • errstr: Chỉ định thông báo lỗi dưới dạng chuỗi

Các tham số tùy chọn trong trình xử lý lỗi tùy chỉnh:

  • errfile: Chỉ định tên file của tập lệnh trong đó xảy ra lỗi, dưới dạng chuỗi
  • errline: Chỉ định số dòng mà lỗi xảy ra, dưới dạng một chuỗi
  • errcontext: Chỉ định một mảng chứa tất cả các biến và giá trị của chúng tồn tại tại thời điểm xảy ra lỗi. Tham số này rất hữu ích cho việc gỡ lỗi

Đây là một ví dụ về chức năng xử lý lỗi tùy chỉnh đơn giản. Trình xử lý này, customError() được kích hoạt mỗi khi xảy ra lỗi, bất kể lỗi tầm thường như thế nào. Sau đó, nó đưa ra các chi tiết lỗi cho trình duyệt và dừng việc thực thi tập lệnh.

<?php
  // Hàm xử lý lỗi
  function customError($errno, $errstr){
      echo "<b>Error:</b> [$errno] $errstr";
  }
?>

Bạn cũng cần báo cho PHP sử dụng hàm xử lý lỗi tùy chỉnh của bạn – chỉ cần gọi hàm set_error_handler() tích hợp, chuyển vào tên của hàm.

<?php
  // Hàm xử lý lỗi
  function customError($errno, $errstr){
      echo "<b>Error:</b> [$errno] $errstr";
  }
 
  // Thiết lập xử lý lỗi
  set_error_handler("customError");
 
  // Thông báo lỗi
  echo($test);
?>

Ghi nhật ký lỗi

Ghi lỗi ra một file text

Bạn cũng có thể ghi nhật ký chi tiết lỗi vào file text, như sau:

<?php
function calcDivision($dividend, $divisor){
    if($divisor == 0){
        trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
    $message = date("Y-m-d H:i:s - ");
    $message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
    $message .= "Variables:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 3, "logs/app_errors.log");
    die("There was a problem, please try again.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>

Gửi lỗi qua Email

Bạn cũng có thể gửi e-mail với các chi tiết lỗi bằng cách sử dụng cùng hàm error_log().

<?php
function calcDivision($dividend, $divisor){
    if ($divisor == 0){
        trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
    $message = date("Y-m-d H:i:s - ");
    $message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
    $message .= "Variables:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 1, "webmaster@example.com");
    die("There was a problem, please try again. Error report submitted to webmaster.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>

Thông báo lỗi

Mặc dù PHP Engine gây ra lỗi bất cứ khi nào nó gặp sự cố với tập lệnh của bạn, tuy nhiên bạn cũng có thể tự kích hoạt lỗi.

Điều này có thể giúp làm cho ứng dụng của bạn mạnh mẽ hơn, bởi vì nó có thể đánh dấu các vấn đề tiềm ẩn trước khi chúng biến thành các lỗi nghiêm trọng.

Để kích hoạt lỗi từ trong tập lệnh của bạn, hãy gọi hàm trigger_error(), gửi thông báo lỗi mà bạn muốn tạo:

trigger_error("There was a problem.");

Xét hàm sau về việc tính toán chia cho hai số.

<?php
function calcDivision($dividend, $divisor){
    return($dividend / $divisor);
}
 
// Gọi hàm
echo calcDivision(10, 0);
?>

Nếu giá trị 0 (số 0) được truyền cho tham số $divisor, lỗi chia cho số 0 được tạo bởi PHP Engine sẽ trông giống như sau:

Warning: Division by zero in C:\wamp\www\project\test.php on line 3

Thông báo này có vẻ không dễ đọc nếu là người dùng. Hãy xem xét ví dụ sau sử dụng hàm trigger_error() tạo thông báo lỗi.

<?php
function calcDivision($dividend, $divisor){
    if($divisor == 0){
        trigger_error("Số bị chia không thể là số 0", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
 
// Gọi hàm
echo calcDivision(10, 0);
?>

Khi chạy lại tập lệnh đã truyền số 0 vào số bị chia, chúng ta sẽ nhận được lỗi như thế này:

Warning: Số bị chia không thể là số 0 in C:\wamp\www\project\error.php on line 4

Như bạn có thể thấy thông báo lỗi được tạo bởi ví dụ thứ hai giải thích vấn đề rõ ràng hơn, thân thiện hơn so với ví dụ trước.

Lời kết

Như vậy bạn đã được học về cách xử lý lỗi trong PHP và các cấp độ lỗi. Xử lý lỗi mềm dẻo để có được một ứng dụng, trang web thân thiện hơn.

Đây cũng là kỹ năng quan trọng để giúp bạn có thể kiểm soát tốt hơn ứng dụng của mình.

Có thể bạn muốn xem

CSS Box Model

Trong hướng dẫn tự học CSS này, bạn sẽ tìm hiểu về CSS Box Model. Hiểu làm thế nào các phần tử có thể trình bày trực quan trên trang web.

Cách CSS Bảng (Table)

Trong bài hướng dẫn tự học CSS này, bạn sẽ tìm hiểu toàn tập cách CSS bảng đẹp, CSS table một cách dễ hiểu nhất.

Leave a reply

Please enter your comment!
Please enter your name here