Tôi đã thấy nhiều chương trình thiếu một lượng kiểm tra lỗi đầy đủ. Nguyên nhân phần lớn là do lập trình viên không dành thời gian để lên một kế hoạch thích hợp cho chương trình của mình, và xác định những vị trí có thể dẫn đến lỗi. Kiểm tra lỗi không nên thực hiện sau khi viết chương trình. Sự thiếu sót trong tầm nhìn trước có thể dẫn đến những lỗi nghiêm trọng, không những gây ra kết quả sai mà thậm chí còn làm hỏng hệ thống (even cause your system to crash)!
1. Mong đợi điều tệ nhất
Mọi chương trình đều có khả năng hư hỏng trong những tình huống sai. Để giảm thiểu những rủi ro như thế, bạn cần lên kế hoạch để:
Kiểm tra kết quả lời gọi hàm
Kiểm tra kết quả lời gọi hệ thống
Đặt mức error_reporting là E_ALL trong tập tin php.ini
1.1. Kiểm tra kết quả lời gọi hàm
Mỗi khi bạn gọi một hàm làm thay đổi nhiều dữ liệu, luôn kiểm tra để đảm bảo rằng kết quả trả về trong phạm vi giá trị được chấp nhận (a range of allowable values).
Trong thí dụ dưới đây, một lỗi illegal division by zero sinh ra trong lần lặp thứ 6 của vòng for ($i được tăng lên 1 trong khi $j bị giảm đi 1). Vào lần thứ 6, khi đó $i = $j = 0.
Mã lệnh (PHP)
<?php
mt_srand((double)microtime() * 10000000);
function do_math ($a, $b)
{
return (($a - $b) * 2) / mt_rand();
}
for ($i = 5, $j = -5; $i > -5; $i--, $j++){
print $j / do_math ($i, $j) . "\n";
}
?>
1.2. Kiểm tra kết quả lời gọi hệ thống
Luôn đảm bảo rằng, khi bạn làm việc với các tiến trình hoặc tập tin ngoài PHP, mọi thứ đều vận hành đúng.
Một thí dụ tuyệt vời là việc kiểm tra đầu ra của một lời gọi hệ thống khi dùng hàm sql_connect(). Xác nhận đầu ra để kiểm tra liên kết đến CSDL là đúng. Làm sai điều này có thể dẫn đến các truy vấn hỏng và mất dữ liệu trong khi thậm chí bạn không biết.
Mã lệnh (PHP)
$conn = @sql_connect ($host, $user, $pass);
if (!$conn) {
die (sprintf ("Error [%d]: %s",
sql_errno (), sql_error ()));
}
1.3. Đặt mức error_reporting là E_ALL trong tập tin php.ini
Hãy đảm bảo bạn cấu hình với mức độ báo lỗi cao nhất có thể. Nếu bạn không đặt nó ở mức cao nhất, ít nhất là trong quá trình tìm lỗi (debugging), bạn có thể bỏ qua những lỗi như là biểu thức chính quy (regular expressions) không hợp lệ và các giá trị không chính xác.
Xem lại lần nữa thí dụ tôi đã đưa trong phần Kiểm tra kết quả lời gọi hàm, ở dưới đây. Giả sử bạn đặt error reporting ở mức thấp,E_ERROR.
Chú ý rằng kết quả in ra khi chương trình thi hành hàm do_math: không có thông báo illegal division by zero đã từng hiện ra lần trước, phần $i=$j=0 đơn thuần không hiện kết quả.
Mã lệnh (PHP)
<?php
error_reporting (E_ERROR);
mt_srand ((double)microtime() * 1000000);
function do_math ($a, $b)
{
return (($a - $b) * 2) / mt_rand();
}
for ($i = 5, $j = -5; $i > -5; $i--, $j++){
print $j / do_math ($i, $j) . "\n";
}
?>
Kết quả hiện ra
-5148.25
-5271
-323.75
-4931
-7713.5
?
-4702.5
-488.5
-928.5
-1394.75
2. Bộ quản lí lỗi tuỳ chỉnh
PHP thường hiển thị các lỗi thực thi (execution errors) ra trình duyệt, ngăn bạn xoá (suppress) hoặc bắt (capture) nó. Tuy nhiên, với PHP4 bạn đã có thể bắt lỗi bằng hàm set_error_handler().
Hàm set_error_handler() có thể được dùng để ghi lại các lỗi xảy ra với chương trình của bạn. Thay vì làm phiền người dùng với các thông báo lỗi, bạn có thể ghi lại cho riêng bạn, bằng cách đặt một hàm quản lí lỗi tuỳ chỉnh (a custom error handling function).
Trong thí dụ dưới, set_error_handler() được dùng để chỉ định hàm error_handler() là bộ quản lí lỗi mặc định.
Khi một lỗi xảy ra, error_handler() được gọi và hàm PHP error_log() được dùng để ghi lỗi vào tập tin error_file.
Nếu mà lỗi thuộc loại E_ERROR, chúng ta sẽ thoát chương trình và in thông báo lỗi.
Mã lệnh (PHP)
<?php
// void error_handler(string type, string message, string file, int line)
// Custom error handler, set by the set_error_handler()
// function.
//
function error_handler ($type,
$message,
$file=__FILE__,
$line=__LINE__)
{
error_log("$message, $file, $line", 3, 'error_file');
if ($type & E_ERROR) {
print 'An error occurred, it has been logged
and it will be addressed.';
exit;
}
}
set_error_handler('error_handler');
?>
1. Mong đợi điều tệ nhất
Mọi chương trình đều có khả năng hư hỏng trong những tình huống sai. Để giảm thiểu những rủi ro như thế, bạn cần lên kế hoạch để:
Kiểm tra kết quả lời gọi hàm
Kiểm tra kết quả lời gọi hệ thống
Đặt mức error_reporting là E_ALL trong tập tin php.ini
1.1. Kiểm tra kết quả lời gọi hàm
Mỗi khi bạn gọi một hàm làm thay đổi nhiều dữ liệu, luôn kiểm tra để đảm bảo rằng kết quả trả về trong phạm vi giá trị được chấp nhận (a range of allowable values).
Trong thí dụ dưới đây, một lỗi illegal division by zero sinh ra trong lần lặp thứ 6 của vòng for ($i được tăng lên 1 trong khi $j bị giảm đi 1). Vào lần thứ 6, khi đó $i = $j = 0.
Mã lệnh (PHP)
<?php
mt_srand((double)microtime() * 10000000);
function do_math ($a, $b)
{
return (($a - $b) * 2) / mt_rand();
}
for ($i = 5, $j = -5; $i > -5; $i--, $j++){
print $j / do_math ($i, $j) . "\n";
}
?>
1.2. Kiểm tra kết quả lời gọi hệ thống
Luôn đảm bảo rằng, khi bạn làm việc với các tiến trình hoặc tập tin ngoài PHP, mọi thứ đều vận hành đúng.
Một thí dụ tuyệt vời là việc kiểm tra đầu ra của một lời gọi hệ thống khi dùng hàm sql_connect(). Xác nhận đầu ra để kiểm tra liên kết đến CSDL là đúng. Làm sai điều này có thể dẫn đến các truy vấn hỏng và mất dữ liệu trong khi thậm chí bạn không biết.
Mã lệnh (PHP)
$conn = @sql_connect ($host, $user, $pass);
if (!$conn) {
die (sprintf ("Error [%d]: %s",
sql_errno (), sql_error ()));
}
1.3. Đặt mức error_reporting là E_ALL trong tập tin php.ini
Hãy đảm bảo bạn cấu hình với mức độ báo lỗi cao nhất có thể. Nếu bạn không đặt nó ở mức cao nhất, ít nhất là trong quá trình tìm lỗi (debugging), bạn có thể bỏ qua những lỗi như là biểu thức chính quy (regular expressions) không hợp lệ và các giá trị không chính xác.
Xem lại lần nữa thí dụ tôi đã đưa trong phần Kiểm tra kết quả lời gọi hàm, ở dưới đây. Giả sử bạn đặt error reporting ở mức thấp,E_ERROR.
Chú ý rằng kết quả in ra khi chương trình thi hành hàm do_math: không có thông báo illegal division by zero đã từng hiện ra lần trước, phần $i=$j=0 đơn thuần không hiện kết quả.
Mã lệnh (PHP)
<?php
error_reporting (E_ERROR);
mt_srand ((double)microtime() * 1000000);
function do_math ($a, $b)
{
return (($a - $b) * 2) / mt_rand();
}
for ($i = 5, $j = -5; $i > -5; $i--, $j++){
print $j / do_math ($i, $j) . "\n";
}
?>
Kết quả hiện ra
-5148.25
-5271
-323.75
-4931
-7713.5
?
-4702.5
-488.5
-928.5
-1394.75
2. Bộ quản lí lỗi tuỳ chỉnh
PHP thường hiển thị các lỗi thực thi (execution errors) ra trình duyệt, ngăn bạn xoá (suppress) hoặc bắt (capture) nó. Tuy nhiên, với PHP4 bạn đã có thể bắt lỗi bằng hàm set_error_handler().
Hàm set_error_handler() có thể được dùng để ghi lại các lỗi xảy ra với chương trình của bạn. Thay vì làm phiền người dùng với các thông báo lỗi, bạn có thể ghi lại cho riêng bạn, bằng cách đặt một hàm quản lí lỗi tuỳ chỉnh (a custom error handling function).
Trong thí dụ dưới, set_error_handler() được dùng để chỉ định hàm error_handler() là bộ quản lí lỗi mặc định.
Khi một lỗi xảy ra, error_handler() được gọi và hàm PHP error_log() được dùng để ghi lỗi vào tập tin error_file.
Nếu mà lỗi thuộc loại E_ERROR, chúng ta sẽ thoát chương trình và in thông báo lỗi.
Mã lệnh (PHP)
<?php
// void error_handler(string type, string message, string file, int line)
// Custom error handler, set by the set_error_handler()
// function.
//
function error_handler ($type,
$message,
$file=__FILE__,
$line=__LINE__)
{
error_log("$message, $file, $line", 3, 'error_file');
if ($type & E_ERROR) {
print 'An error occurred, it has been logged
and it will be addressed.';
exit;
}
}
set_error_handler('error_handler');
?>
Nguồn http://zensoft.vn/showArticle.aspx?ID=10684
Tin mới hơn:
- Lỗi chết người trong php
- Lập trình PHP như các ngôn ngữ khác
- Dùng nhầm Biểu thức Chính quy
- Lạm dụng Hướng đối tượng (HĐT)
Tin cũ hơn:
- Không suy nghĩ thấu đáo: CSDL & SQL
- Không tuân thủ các quy ước đặt tên
- 21 lỗi thường gặp khi lập trình với PHP (phần 9)
- 21 lỗi thường gặp khi lập trình với PHP (phần 7)
- 21 lỗi thường gặp khi lập trình với PHP (phần 8)