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. <?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"; } ?> 12. Thiếu sự kiểm lỗi 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'); ?> 11. Lạm dụng Hướng đối tượng (HĐT) Mô hình hướng đối tượng là một khái niệm tuyệt vời. Nó có rất nhiều lợi điểm, mà đáng chú ý nhất là khả năng dùng lại mã dễ dàng. Tuy nhiê, theo như chúng ta được hiểu: PHP không phải là một ngôn ngữ HĐT. Mặc dù PHP có một sự hỗ trợ đầy đủ về HĐT, nó không hiệu quả lẫn không khôn ngoan nếu dùng tính năng HĐT của nó khi bạn có các hàm khác để đạt được cùng kết quả. Lí do là sự hỗ trợ HĐT của PHP không được phát triển mạnh. Trong khi có hầu hết các phần tử chính yếu, PHP vẫn còn thiếu vài tính năng cao cấp (như các khái niệm protected, private) mà một ngôn ngữ HĐT thực sự (thí dụ như C++ , Java) phải có. Các mã hỗ trợ HĐT của PHP không được tinh chỉnh và cũng không hiệu quả. Nghĩa là nếu bạn dùng mô hình HĐT trong PHP, bạn có thể làm chậm chương trình đáng kể. Nói chung, một ứng dụng dùng HĐT sẽ chậm đi, cũng như là bạn dùng eval() thì sẽ chậm hơn là dùng mã bình thường. Để minh hoạ đầy đủ hơn việc HĐT có gì đó không tốt, tôi đã từng phải dùng những tính năng và khái niệm cao cấp của PHP, một vài trong số đó thậm chí chưa có tài liệu chỉ dẫn. 1. Chúng ta có thể làm gì mà không cần HĐT? Nếu bạn chuyển sang PHP từ các ngôn ngữ như Java hay C++ (nơi bạn bạn thực sự không thể tạo các chương trình phức tạp mà không dùng các tính năng HĐT), việc bỏ qua khả năng HĐT của PHP có thể sẽ khó khăn. Dù sao, tôi vẫn có thể trấn an bạn là các chương trình rất mạnh có thể được viết mà không dùng mất cứ khái niệm và mô hình HĐT nào (PHP được viết bằng C, ngôn ngữ không hỗ trợ HĐT). Để dành cho những ai không quen với kĩ năng phi-HĐT, dưới đây là vài kĩ thuật để tạo chương trình có tính kết dính và dễ mở rộng mà không dùng mô hình HĐT: * Tạo một API * Tạo một trình tự tên * Nhóm các hàm liên quan vào một tập tin 1.1. Tạo một API Áp dụng 3 lớp cho chương trình của bạn: * Thứ nhất, các hàm thực sự thực hiện công việc của bạn * Thứ hai, một hàm API. Đây là hàm giúp bạn xây dựng các chương trình đặc thù * Chương trình MortgageRate.php Mã lệnh (PHP) <?php // The internal functions are layer 1 // Internal function to calculate the correct // interest rate to be used given the amount per month // and the time it is to be paid in function _mort_find_interest_rate ($total) { if ($total < 30000) return (7.4); elseif ($total > 30000) return (3.2); elseif ($total > 50000) return (2.5); else return (1.7); } // The API is layer 2 // double calculate_mortgage_rate (int money, int time, int month) // Calculate the mortgage rate given the // the total money, time its paid over and // the intervals function calculate_mortgage_rate ($money, $time, $month) { $rate = _mort_find_interest_rate ($money) / 100; $money /= ($time / $month); return ($rate * $money) + $money; } ?> CalcMortgage.php Mã lệnh (PHP) <?php // The actual application is layer 3 // $money, $time and $period are submitted // from a form include_once 'MortgageRate.php'; $price = calculate_mortgage_rate ($money, $time, $period); print "Your $period month cost is $price"; ?> 1.2. Tạo một trình tự tên và luôn tuân thủ Một trong những vấn đề chính trong bất cứ một dự án lớn nào là sự xung đột về tên. Các lớp có thể phân đoạn tên. Do đó, các lớp khác nhau có thể: * Được gán một thuộc tính với tên giống nhau * Chứa các phương thức với tên giống nhau Thí dụ, lớp Phillips và lớp Normal có thể cùng có phương thức tên screwdriver. Nói chung, trước khi bắt đầu một dự án lớn nào, bạn nên có một trình tự tên cho mọi thứ, cụ thể là cách bạn tách các biến toàn cục ra các biến thông thường, cách định nghĩa hàm trong thư viện v.v. 1.3. Nhóm các ý niệm chung vào một tập tin Nhóm các hàm API tương tự vào chung một tập tin cũng giống như nhóm các phương thức tương tự vào một lớp. Cố gắng tưởng tượng mỗi tập tin bạn tạo là một lớp, mỗi hàm trong đó là một phương thức. Bằng cách này, các hàm của bạn sẽ có định nghĩa và cấu trúc sáng sủa. Thí dụ, bạn có thể muốn nhóm mọi hàm liên quan đến truy cập CSDL vào một tập tin DB.php. 2. HĐT, giống mọi thứ, tốt khi có điều độ Để tôi làm sáng tỏ một việc. Tôi không phải đang cố biện hộ để bạn từ bỏ hẳn HĐT trong PHP. Đúng ra, tôi chỉ đang cố cảnh báo bạn đừng nên dùng PHP như Java hay C++, nơi mà HĐT có thể dùng thoải mái. Hãy cẩn thận đánh giá lợi và hại trước khi bạn dùng một tiếp cận HĐT với PHP. |
Thêm vào trang Google +
Số lần xem : 3718
Đánh giá