Ghi và xử lý lỗi trong PHP
Trong hướng dẫn này, bạn sẽ học cách sử dụng các hàm xử lý lỗi của PHP để đối phó với các điều kiện lỗi một cách khéo léo.
Lỗi trong PHP
Đôi khi ứng dụng của bạn sẽ không chạy như mong muốn, dẫn đến lỗi. Có một số lý do có thể gây ra lỗi, ví dụ:
- Máy chủ Web có thể hết dung lượng lưu trữ
- Người dùng có thể đã nhập giá trị không hợp lệ trong biểu mẫu dữ liệu đầu vào
- Tệp hoặc bản ghi cơ sở dữ liệu mà bạn đang cố gắng truy cập có thể không tồn tại
- Ứng dụng có thể không có quyền ghi vào 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à lỗi thời gian chạy (runtime errors), vì chúng xảy ra tại thời điểm tập lệnh chạy. Chúng khác biệt với các lỗi cú pháp cần được sửa trước khi tập lệnh chạy.
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 một cách rõ ràng nhất. 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.
Các mức độ lỗi
Thông thường, khi có sự cố khiến tập lệnh không chạy đúng cách, công cụ PHP sẽ gây ra lỗi. Mỗi lỗi được biểu diễn bằng một giá trị số nguyên và một hằng số liên quan. Bảng sau liệt kê một số mức độ lỗi phổ biến:
Mức độ lỗi | Giá trị | Nội dung |
---|---|---|
E_ERROR |
1 |
Một lỗi thời gian chạy nghiêm trọng, không thể khôi phục được.Việc thực thi tập lệnh bị dừng ngay lập tức. |
E_WARNING |
2 |
Một cảnh báo thời gian chạy.Nó không gây tử vong 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 tập lệnh không bị dừng lại. |
E_NOTICE |
8 |
Một thông báo thời gian chạy.Cho biết rằng tập lệnh đã gặp phải điều gì đó có thể là lỗi, mặc dù tình huống này cũng có thể xảy ra khi chạy tập lệnh bình thường. |
E_USER_ERROR |
256 |
Một thông báo lỗi nghiêm trọng do người dùng tạo.Điều này giống như mộtE_ERROR , ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàmtrigger_error() chứ không phải công cụ PHP. |
E_USER_WARNING |
512 |
Một thông báo cảnh báo không nghiêm trọng do người dùng tạo.Điều này giống như mộtE_WARNING , ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàmtrigger_error() chứ không phải PHP.động cơ |
E_USER_NOTICE |
1024 |
Một thông báo thông báo do người dùng tạo.Điều này giống như mộtE_NOTICE , ngoại trừ nó được tạo bởi tập lệnh PHP bằng cách sử dụng hàmtrigger_error() chứ không phải công cụ PHP. |
E_STRICT |
2048 |
Không hoàn toàn là 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_ALL |
8191 |
Tất cả các lỗi và cảnh báo, ngoại trừE_STRICT trước PHP 5.4.0. |
Để biết thêm các cấp độ lỗi, vui lòng xem tài liệu tham khảo về Cấp độ lỗi PHP .
Công cụ PHP kích hoạt 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 các thông báo lỗi thân thiện hơn với người dùng. Bằng cách này, bạn có thể làm cho ứng dụng của mình chuyên nghiệp hơn. Phần sau đây mô tả một số phương pháp phổ biến được sử dụng để xử lý lỗi trong PHP:
Xử lý lỗi cơ bản bằng cách sử dụng hàm die()
Hãy xem xét ví dụ sau đây chỉ đơn giản là cố gắng mở một tệp văn bản để chỉ đọc.
Ví dụ
<?php
// Try to open a non-existent file
$file = fopen("sample.txt", "r");
?>
Nếu tệp không tồn tại, bạn có thể gặp lỗi như sau:
Ví dụ
<?php
if(file_exists("sample.txt")){
$file = fopen("sample.txt", "r");
} else{
die("Lỗi: Tệp bạn đang cố gắng truy cập không tồn tại.");
}
?>
Bây giờ nếu bạn chạy tập lệnh trên, bạn sẽ nhận được thông báo lỗi như sau:
Như bạn có thể thấy bằng cách thực hiện một kiểm tra đơn giản xem tệp có tồn tại hay không trước khi cố gắng truy cập nó, chúng ta có thể tạo ra một thông báo lỗi có ý nghĩa hơn đối với người dùng.
Hàm die()
sử dụng ở trên chỉ đơn giản là hiển thị các thông báo lỗi tùy chỉnh và chấm dứt các kịch bản hiện tại nếu tập tin 'sample.txt' không được tìm thấy.
Tạo trình xử lý lỗi tùy chỉnh
Bạn có thể tạo hàm xử lý lỗi của riêng mình để đối phó với lỗi thời gian chạy 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 tốt hơn các lỗi, 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 e-mail, cố gắng khắc phục sự cố và tiếp tục, thoát khỏi quá trình 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 và errstr), tuy nhiên, nó có thể tùy chọn chấp nhận thêm ba tham số (errfile, errline và errcontext), như được mô tả bên dưới:
Tham số | Nội dung |
---|---|
Bắt buộc- Các thông số sau là bắt buộc | |
errno | Chỉ định mức độ của lỗi, dưới dạng số nguyên.Điều này tương ứng với hằng số mức lỗi thích hợp (E_ERROR ,E_WARNING v.v.) |
errstr | Chỉ định thông báo lỗi dưới dạng một chuỗi |
Tùy chọn- Các thông số sau là tùy chọn | |
errfile | Chỉ định tên tệp của tệp kịch bản đã xảy ra lỗi, dưới dạng một chuỗi |
errline | Chỉ định số dòng xảy ra lỗi, 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.Hữu ích để 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 bất cứ khi nào xảy ra lỗi, bất kể mức độ nhỏ như thế nào. Sau đó, nó xuất thông tin chi tiết về lỗi cho trình duyệt và dừng việc thực thi tập lệnh.
Ví dụ
<?php
// Error handler function
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
?>
Để yêu cầu 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 tích hợp sẵn set_error_handler()
, truyền vào tên của hàm xử lý lỗi tùy chỉnh.
Ví dụ
<?php
// Error handler function
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
// Set error handler
set_error_handler("customError");
// Trigger error
echo($test);
?>
Ghi nhật ký lỗi
Ghi nhật ký thông báo lỗi trong tệp văn bản
Bạn cũng có thể ghi chi tiết về lỗi vào tệp nhật ký, như sau:
Ví dụ
<?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 thông báo lỗi bằng e-mail
Bạn cũng có thể gửi e-mail với chi tiết lỗi bằng hàm error_log() .
Ví dụ
<?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, "admin@domain.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.";
?>
Kích hoạt lỗi
Mặc dù công cụ PHP kích hoạt 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, vì nó có thể phát hiện các vấn đề tiềm ẩn trước khi chúng chuyển thành lỗi nghiêm trọng.
Để kích hoạt lỗi từ bên trong tập lệnh của bạn, hãy gọi hàm trigger_error()
, chuyển vào thông báo lỗi mà bạn muốn tạo:
Hãy xem xét hàm sau đây để tính phép chia hai số.
Ví dụ
<?php
function calcDivision($dividend, $divisor){
return($dividend / $divisor);
}
// Calling the function
echo calcDivision(10, 0);
?>
Nếu một giá trị không (0) được truyền vào cho tham số $divisor, thì lỗi do PHP engine tạo ra sẽ trông giống như sau:
Thông báo này trông không có nhiều thông tin. Hãy xem xét ví dụ sau sử dụng hàm trigger_error()
để tạo ra lỗi.
Ví dụ
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
// Calling the function
echo calcDivision(10, 0);
?>
Bây giờ tập lệnh tạo ra thông báo lỗi này:
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 so với ví dụ trước.