Xem mẫu

  1. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes B ài vi ết này dành cho nh ững l ập trình viên PHP quan t âm đế n việc tránh nh ững lỗ i thường gặp khi sử dụ ng PHP. Ng ười đọc ph ải bi ết các cú ph áp củ a PHP, và n ên bi ết công dụ ng củ a các hàm trong PHP. Một trong nh ữ ng đ iểm m ạnh nh ất của PHP vô tình trở thành m ộ t trong nhữ ng đ iểm yếu nh ất của n ó: tính dễ sử dụng . Nhi ếu ng ười chọn PHP vì tí nh d ễ sử d ụng, đã kh ông nh ận ra r ằng: sử dụng đú ng PHP còn kh ó h ơn các ng ôn ng ữ kh ác. Trong loạt b ài n ày sẽ l ần l ượt nêu ra 21 l ỗi, từ nh ữ ng sai l ầm gi áo khoa (làm script trở nên chậm và kh ó qu ản l í ) đến nh ững sai l ầm chết người - có thể xem l à ngu ồn gốc củ a nh ữ ng sai l ầm sơ đẳ ng. PHẦN 1: 7 LỖI GIÁO KHOA  21. S ử d ụng printf() kh ông th ích h ợp Hàm printf () dùng để in d ữ li ệu có đị nh dạng Nó có thể được dùng, thí dụ, khi bạn m ột in m ột số ki ểu double vớ i 2 số lẻ, hoặc trong bất kì t ình hu ống n ào bạn mu ố n thay đổi đị nh d ạng trước khi in. Thí dụ dưới đây minh ho ạ cách dùng đú ng củ a printf (): đị nh d ạng số Pi với độ chí nh xác theo ý mu ốn M ã l ệnh (PHP) Chú ý . T ôi đã từ ng gặp nh ữ ng ng ười sợ dùng printf (), thay vào đó l ại d ùng nh ững hàm đị nh dạng tự vi ết, dài đến 30- 40 dòng, trong đi m ột câu printf () có thể làm m ọ i thứ anh ta mong mu ốn. Nhi ếu l ập trình viên d ùng sai printf (): in các bi ến, các gi á trị trả về của hàm ho ặc thỉnh thoảng, chỉ là dữ li ệu thông thường. Thường xảy ra trong hai t ình hu ống:  Câu l ệnh print() thí ch h ợp hơn  Hi ển thị gi á trị trả về của m ột hàm 1. Khi nào print() th ích hợ p hơn? Các l ập trình viên thường sử dụ ng printf () trong khi chỉ print() l à đủ . Xét thí dụ sau: Hàm print() có thể dù ng thay cho printf () nh ư sau: 1 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  2. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes print "Ten cua tui la: $name\n\n Hien dang la: $nghenghiep, $diachi\n\n Lien he voi toi qua Email: $email\n\n"; Khi kh ô ng cần đị nh dạng sử li ệu, dù ng print() thay cho printf () có nh ữ ng l ợi í ch sau:  Thi hành nhanh h ơn: hàm printf() đị nh d ạng dữ li ệu củ a bạn trước khi hi ển thị , nó sẽ chậm hơn print() hoặc echo()  M ã sáng sủ a: hãy xem, d ùng hàm printf() sẽ l àm cho ng ười đọc hơi bị lẫn l ộn (tất nhi ên trừ khi họ có n ền tảng C). Nó đò i h ỏi ki ến thứ c về cú ph áp printf() (thí d ụ, %s thay cho chu ỗi còn %d l à số) và về ki ểu bi ến 2. Dùng printf() để xu ất d ữ li ệu tr ả v ề từ gọi h àm Một l ỗi thường gặp kh ác l à d ùn printf () để xu ất dữ li ệu trả về từ gọi hàm, thí dụ nh ư hàm đếm dưới đâ y: Khi xu ất gi á trị do h àm trả về, to án tử . n ên dùng để nối trong print(), nh ư d ưới đây: Dù ng to án tử . nhanh hơn vi ệc d ùng printf () 20. Á p dụng sai ngữ ngh ĩ a (semantics) Nhi ều l ập trì nh viên sử dụ ng PHP m à kh ông bi ết đế n nh ữ ng đ iểm tinh tế của ng ôn ng ữ này. Một trong nh ữ ng đ iểm đó l à sự kh ác nhau gi ữ a cú ph áp (syntax) và ng ữ ngh ĩa (semantics).  C ú pháp: nh ững quy tắc đị nh ngh ĩ a một phần t ử. Thí dụ : d ấu $ để trước dù ng đị nh ngh ĩ a bi ến, d ùng dấu () và các tham số đị nh ngh ĩa một h àm...  Ng ữ ngh ĩ a: nh ững quy tắc áp d ụng trong cú pháp. Thí dụ : một h àm có 2 bi ến đị nh ngh ĩ a bởi cú ph áp của n ó, hai bi ến n ày có kiểu string - đó l à ng ữ ngh ĩa. Trong m ộ t ng ôn ng ữ lỏng l ẻo nh ư PHP, b ạn có nhi ều l ự a ch ọn để viết l ệnh. C ác bi ến kh ông cần có ki ểu xác đị nh... Thí dụ sau m ở t ập tin và in từ ng d òng: Thí dụ trên sẽ tạo l ỗi: Warning: Supplied argument is not a valid File-Handle resource in C:\Inetpub\wwwroot\tst.php on line 4. 2 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  3. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes Đó là do bi ến $fp đặt trong dấu nh áy kép nên được chuyển thành chu ỗi. Thế m à hàm fopen() nh ận m ột đị nh danh t ài nguy ên (resource identif ier) trong tham số đầu củ a n ó, chứ kh ông nh ận m ột chu ỗi. Để gi ải quy ết vấn đề, bạn chỉ đơn gi ản b ỏ d ấu nh áy kép đ i 1. C ó th ể tr ánh vi ệc áp dụng sai ng ữ ngh ĩ a? Our example above generated an error statement. But PHP enables you to customize your scripts to fit a unique scenario or output requirement. So, it is at least theoretically possible to "get away" with misapplying a semantic. Tôi kh ông hi ểu, nh ư ng dị ch thế này được kh ông? Thí d ụ trên củ a ch úng ta tạo ra m ột thông b áo lỗi. Nh ư ng PHP cho ph ép bạn tuỳ bi ến các script để thí ch h ợp với m ột kịch bản kh ác thường ho ặc với các đòi hỏ i củ a thông tin ra. Do đó, í t nh ất trên l í thuyết, b ạn có kh ả n ăng tránh việc áp dụ ng sai ng ữ ngh ĩa. Vậy, b ạn cần bi ết nh ữ ng h ậu qu ả có thể có (possible outcomes) nếu bạn quy ết đị nh h ọc về ng ữ ngh ĩ a. Áp d ụng sai dẫn đến nhữ ng lỗi kh á tinh vi n ếu bạn kh ông ch ú ý. Nếu bạn mu ốn tuỳ bi ến script, bạn cần hi ểu nhữ ng chủ đề chí nh sau:  Ki ểu: trong PHP, mỗi bi ến có mộ t kiểu xác đị nh ở mộ t thời đ iểm xác đị nh, cho d ù bạn có thể tự do chuy ển đổ i ki ểu một bi ến. Nói một cách kh ác, kh ông có bi ến n ào l ại kh ông kèm theo tí nh ch ất của ki ểu của nó. PHP có 7 ki ểu cơ bản: boolean, resource, integer, doubl e, string, array và object.  Tầm vực: trong PHP, mỗi bi ến có một t ầm vự c riêng. Tầm vự c bi ến quy đị nh bi ến có thể được truy cập từ đâ u, tồn tại trong thời gian n ào. Hiểu sai kh ái ni ệm cơ bản về "t ầm vự c" dẫn đế n nh ữ ng l ỗi sai tinh tế và cả nh ững l ỗi l ớn.  php.ini: khi vi ết một script chạy ở nhi ều môi trường kh ác nhau, cần bi ết rằng kh ông ph ải mọi cấu hì nh PHP đều nh ư nhau. Do đó, cần thiết nh ữ ng lệnh ki ểm tra để đảm bảo script củ a bạn chạy tốt trong cấu hì nh PHP củ a ng ười kh ác. 19. Thi ếu ghi ch ú Theo ý tôi, m ã ngu ồn thiếu ghi chú l à căn nguy ên của sự lập trì nh ích kỉ . Nó d ẫn tới nh ữ ng hi ệu ch ỉnh sai l ầm, hi ểu sai ý ngh ĩ a và làm người đọ c m ệt m ỏi. Nói chung, lập trình ghi chú (inline documentation) được m ọi ng ười kh ẳng nh ận là đi ều tốt, nh ư ng hi ếm khi nó tồn t ại. Một vấn đề kh ác l à qu á nhi ều ghi ch ú. D ù hi ếm g ặp, như ng nó làm cho các đoạn m ã bị cắt vụn, g ây ra sự kh ó theo d õi. Dưới đâ y l à m ột thí dụ:
  4. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes // In ra tuoi ca nhan print "$idx years old\n\n"; } // Ket thuc ma PHP ?> 1. Bao nhi êu ghi chú th ì đủ ? Nhi ếu đế n m ứ c n ào, đi ều đó tuỳ thu ộc ng ân sách củ a bạn, vào chí nh sách của công ty và vào độ phứ c tạp củ a ch ương trì nh. Tuy nhi ên, cũng có m ột vài g ợi ý cho bạn  Lu ôn có một mô t ả ng ắn về mục đí ch của hàm ngay trước đị nh ngh ĩa của hàm đó  Thêm ghi chú vào nh ữ ng chỗ có thể b ị hack, ho ặc nh ữ ng chỗ tưởng r ằng sai nh ưng l ại chạy đú ng  Nếu một đoạn mã nào đó có thể g ây nh ầm l ẫn, h ãy thêm một ít ghi chú về mục đí ch của đo ạn đó. Sau này bạn sẽ thấy được l ợi í ch của nó  Dù ng một ki ểu ghi chú nh ất qu án, /* */ ho ặc l à // (tr ánh dù ng #) Dưới đây l à m ột thí dụ về ghi chú t ốt: 18. Nhi ều biến, tốn nhi ều thờ i gian Có vài người bị ám ảnh bởi bi ến trung gian. Tôi kh ông thể hi ểu nổi tại sao ai đó có thể vi ết nh ư thế n ày: 4 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  5. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes Tại sao ph ải d ùng bi ến trung gian? Nó kh ông cần thi ết Rủ i thay, có vẻ nh ư r ất nhi ều ng ười kh ó bỏ được thói quen xấu này. Bi ến t ạm làm ch ậm thời gian thi h ành chương tì nh của bạn. Tốt h ơn là n ên b ỏ qua đó và gộp các lời gọi h àm với nhau. Nh ững người dùng bi ến t ạm thường l àm ch ương của họ chạy chậm đến 25%. Một lí do kh ác để tránh có qu á nhi ều bi ến tạm l à vì trông n ó kh ông được đẹp m ắt. Trong hai thí dụ trên, thí dụ n ào súc tích hơ n? Thí dụ nào l àm con m ắt d ễ chị u h ơn? Dùng qu á nhi ều bi ến tạm có thể dẫn đế n m ã ch ương trì nh kh ó đọ c và kh ông súc tí ch. 1. Lợ i điểm của dù ng bi ến tạm Các bi ến t ạm có l ợi trong vi ệc thay thế các hàm hay bi ểu thứ c dài l ê thê. Nó có vai trò nh ư b í danh gi ả. Đ iều n ày đặ c bi ệt đú ng khi bạn dùng m ột hàm hay bi ểu thức nhi ều lần. Xem xét thí dụ đây, nó kh ông dù ng nhi ều bi ến hơn m ứ c tối thi ểu // string reverse_characters(string str) // Reverse all of the characters in a string. function reverse_characters ($str) { return implode ("", array_reverse (preg_split("//", $str))); } Nội dung trong hàm implode() dài và do đó kh ó đọc. Dùng m ột hoặc nhi ều bi ến t ạm có thể gi ú p chú ng ta: // string reverse_characters(string str) // Reverse all of the characters in a string. function reverse_characters ($str) { $characters = preg_split ("//", $str); $characters = array_reverse ($characters); return implode ("", $characters); } 2. C ác lu ật chung của ng ón tay cái Khi quy ết đị nh có dù ng bi ến tạm ho ặc kh ô ng, bạn n ên suy ngh ĩ về 2 câu h ỏi:  Bạn có dù ng bi ến đó í t nh ất hai l ần?  Tí nh đọ c đượ c củ a m ã có tăng đá ng kể kh ông? Nếu ít nh ất m ột câu trả l ời l à có, thì nên dùng bi ến tạm. C òn kh ông, vứ t nó đ i và tổ h ợp các hàm lại (nếu cần). 17. Vi ết lại các h àm có sẵn Một số nơi ph ổ bi ến m ã ngu ồn các script PHP ch ủ trương đổi t ên các hàm sẵn có để tạo sự d ễ d àng cho các lập trì nh viên chuy ển từ VB sang. Thí dụ :
  6. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes return strlen ($str); } ?> Lại có m ột số ng ười cố gắng viết l ại các hàm PHP thông dụ ng thay vì đ i h ọc về hàm đó trong các tài li ệu PHP cung cấp. Có ít nh ất 2 lí do để kh ông n ên l àm đi ều này. Thứ nhất, và trên nh ất, n ó l àm cho nh ữ ng ng ười đọ c (và sử a) chương trì nh của b ạn kh ó hi ểu và cảm thấy có qu á nhi ều h àm dư thừ a. Họ tự h ỏi tại sao b ạn l ại đi đị nh ngh ĩa hàm theo ki ểu đó , thay vì sử dụng các hàm đị nh ngh ĩa sẵn bởi PHP. Thứ hai, đị nh ngh ĩa h àm nh ư vậy cũ ng sẽ làm ch ậm ch ương trì nh củ a b ạn (một cách kh ông cần thiết). Kh ông chỉ phải xử l í nhi ều m ã h ơn, m à m ỗi l ần g ọi hàm do bạn đị nh ngh ĩ a, bạn đã t ốn thời gian cho ch ính hàm đó, trước khi h àm nguy ên thu ỷ được gọi. 1. Tr ánh viết lại các h àm có sẵn Hãy đương đầu với nó. Đô i khi thật là kh ó để tránh chuy ện n ày. Trước tiên, m ột l ập trì nh vi ên kh ông thể theo kịp các hàm củ a PHP ngay được. Và ai có thời gian m à tra cứ u. Tại sao kh ông viết l ại cho kho ẻ? Cách l àm của tôi l à lu ôn có sẵn m ột t ài li ệu chỉ dẫn PHP (PHP manual ) m ỗi khi viết chương trì nh (tác gi ả bài này dù ng m ột bản PDF có tạo ch ỉ m ụ c, ri êng tôi, ng ười dị ch, thì d ùng m ột tài li ệu CHM đầy đủ thông tin và có cả g óp ý củ a người sử d ụng mà b ạn có thể l ấy ở http://www.php.net/docs.php) . Sau đó , m ỗi khi đị nh viết m ộ t hàm mở r ộng cho PHP, tôi đọc l ướt qua tài li ệu để xem h àm đó có ch ưa. Tuy nhi ên, cần ch ú ý là, do bản chất m ã ngu ồn m ở củ a PHP, bạn có thể tì m được các hàm do ng ười dù ng đị nh ngh ĩa trước khi nó được thêm vào PHP (thí d ụ nh ư h àm tì m phần t ử kh ác nhau gi ữ a hai m ảng). Đi ều này kh ông có ngh ĩ a là bạn ph ải hi ệu chỉ nh l ại m ã (This doesn't necessarily mean that you should have to correct the code. - don't understand) 16. Kh ông tách bi ệt ph ần server và client Vài l ập trì nh vi ên cố kết n ối cả ch ương trì nh với nhau, ngh ĩ a là gh ép chung m ã HTML (client-side - ph ần kh ách) với m ã PHP (server-side - ph ần chủ ) vào trong m ột tập tin lớ n. Mặc dù đi ều này t ốt cho các site nh ỏ, nh ư ng nó có thể trở thành vấn đề l ớn khi các site đó trở nên l ớn hơn và được bổ sung thêm t ính n ăng. L ập trì nh theo cách này l àm n ảy sinh vấn đề kh ó bảo trì và các t ập tin trở n ên cồng kềnh. 1. Hàm API Khi mu ố n tách bi ệt phần kh ách - ch ủ, bạn có vài l ựa chọn. M ột cách là viết nh ữ ng h àm hi ển thị n ội dung linh độ ng và đặt chú ng đú ng ch ỗ trong trang web. Thí dụ dưới đây minh ho ạ đ iều n ày: index.php - phần kh ách HTML < ?php include_once ("site.lib"); ?> < html > < head > < title> < /title> < /head > < body> < h1 > < ?php print_header (); ? > < /h1 > < table border =" 0 " cellpadding=" 0 " cellspacing=" 0 "> < tr> 6 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  7. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes < td width=" 25% "> < ?php print_links (); ? > < /td> < td> < ?php print_body (); ? > < /td> < /tr> < /table > < /body > < /html > site.lib - ph ần chủ Nh ư bạn thấy trong thí dụ trên, tách bi ệt kh ách ch ủ l àm tăng tí nh dễ đọc trong ch ương trì nh của b ạn. Một lợi í ch kh ác là m ột khi b ạn đã có các hàm API hi ển thị n ội dung, b ạn có thể để cho thiết kế viên tham gia thay đổi b ố cụ c m à kh ông cần sử a m ã ch ương tr ì nh. 1.1. L ợi ích củ a h àm AP I  Tương đối sáng sủa  Nhanh, hầu nh ư kh ông lãng phí thời gian (overhead) 1.2. Bất lợ i 7 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  8. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes  Kh ông sáng sủa và d ễ dàng bằng hệ thố ng m ẫu (template system)  Cần m ộ t í t ki ến thứ c PHP để sử a m ẫu 2. Hệ th ống khu ô n mẫu Một cách kh ác để tách bi ệt kh ách chủ l à dù ng hệ thống khu ôn m ẫu. Ngh ĩ a l à, có m ột số đánh d ấu nội dung sau đó dù ng chương trì nh ph ân t ích, thay thế các đánh d ấu đó bằng thông tin cần thi ết. Thí dụ , b ạn có thể tạo m ột tập tin nh ư thế này: HTML < html > < head > < title>%%PAGE_TITLE%%< /title> < /head > < body %%BODY_PROPERTIES%% > < h1 >%%PAGE_TITLE%%< /h1 > < table border =" 0 " cellpadding=" 0 " cellspacing=" 0 "> < tr> < td width=" 25% ">%%PAGE_LINKS%%< /td> < td>%%PAGE_CONTENT %%< /td> < /tr> < /table > < /body > < /html > Sau đó có thể vi ết ch ương trì nh ph ân t ách tập tin, thay thế các thông tin trong dấu cách %% b ằng các thông tin thích h ợp. Ghi chú : m ột lớp h ỗ trợ h ệ thống khu ôn m ẫu kh á tốt l à l ớp FastTemplate, có ở www.thewebmasters.net 2.1. Ưu đ iểm của hệ thống khu ôn mẫu  Rất trong sáng  Kh ông cần ki ến thức PHP để sửa khu ôn m ẫu 2.2. Nh ược đ iểm  Ch ậm h ơn, bạn cần ph ân t ách tập tin khu ôn m ẫu, sau đó xu ất ra  Vi ệc hi ện thự c phứ c tạp h ơn 15. Dù ng các cấu tr úc lỗ i thời Có nhi ều ng ười cứ dùng m ãi các m ã và thư viện l ỗi thời. Thí dụ nh ư họ đã vi ết m ột hàm dù ng ở PHP 2, và vẫn còn dù ng n ó ở PHP 4, m ặc d ù m ột h àm có cùng m ụ c đí ch nh ư thế đã được thêm vào ở PHP 3 Dù ng các cấu trú c l ỗi thời có thể l àm ch ậm ch ương trình của bạn, cũng nh ư l àm cho nó trở nên kh ó hi ểu. Ng ười đọ c các ch ương trì nh củ a bạn có thể kh ông quen với các h àm l ỗi thời của PHP. Tuy nhi ên, khi ph át hi ện m ột đoạn m ã l ạc hậu, b ạn đừ ng ngh ĩ r ằng cần ph ải thay thế nó . Ch ỉ cần ch ắc ch ắn rằng bạn sẽ kh ông dù ng nó cho các chương trình viết trong tương lai. Một thí dụ về cấu trúc l ỗi thời, m à nhi ều ng ười có vẻ cố n ắm lấy, l à cú pháp beginControlStruc ture .. endControlStruc ture ;
  9. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes // Bad/Outdated Practice while (1): print "5"; if ($idx++ == 5): break; endif; endwhile; // Better Practice // (the code could be optimized though) while (1) { print "5"; if ($idx++ == 5) { break; } } ?> Đâ y l à m ột thói quen xấu vì  Nó kh ông đượ c d ùng r ộng rãi, cho nên nhi ều ng ười học sẽ b ị l ẫn l ộn gi ữ a hai cú ph áp Nó kh ông tương thí ch với ng ôn ng ữ kh ác, ngh ĩa l à n ó trở nên kh ó đọc đối với nh ững  ng ười trong giai đoạn qu á độ (mới chuy ển từ một ngôn ngữ nào đó sang PHP)  Quan trọng nh ất, là một ngày nào đó t ính năng n ày sẽ bị xo á xổ, bắt bu ộc bạn ph ải vi ết lại toàn bộ mã có d ùng nó. Dấu ngo ặc nh ọn lu ôn lu ôn l à một ph ần của ng ôn ng ữ PHP. Ở trên chỉ l à m ột thí dụ về cấu trú c l ỗi thời. Nó còn nhi ều n ữa. Nh ư m ột quy t ắc, b ạn nên theo nh ữ ng các vi ết trong t ài li ệu PHP. Hầu hết nó được cập nh ật m ới. Nó cũ ng dù ng các h àm m ới nh ất củ a PHP trong thí dụ của m ì nh. Nên thường xuy ên ki ểm tra t ài li ệu khi bạn có ý mu ốn m ở rộng tí nh n ăng n ào đó của PHP. Theo cách này, bạn sẽ kh ông phải viết l ại các hàm có sẵn. Tổng kết Trong bài n ày bạn đã đ i qua 7 trên tổng số 21 lỗi m à lập trì nh viên PHP m ắc ph ải. Nh ững l ỗi gi áo khoa này bao gồm:  Sử dụ ng sai h àm printf()  Áp d ụng sai ng ữ ngh ĩa  Thi ếu tài li ệu trong mã ngu ồn  Dù ng qu á nhi ều biến tạm  Vi ết l ại các hàm có sẵn  Kh ông tách bi ệt phần kh ách/chủ  Dù ng các cấu tr úc l ỗi th ời 9 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  10. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes PHẦN 2 – LỖI NGHIÊM TRỌNG  14. Kh ông tuân th ủ các quy ước đặ t tên Một trong nh ữ ng l ỗi nghi êm trọng m à người lập trì nh có thể ph ạm phải là đị nh ngh ĩ a m ột quy ước đặt t ên t ồi. Tô i đã tiếp qu ản nhi ều dự án m à trong đó tôi ph ải bỏ ra r ất nhi ều thời gi ờ chỉ để hi ểu chương trì nh, do l ập trì nh vi ên đặt tên các bi ến là $fred và $barney thay cho $email và $name. Tôi đang đề cập đến m ột d ự án m à ng ười l ập trì nh cũ đã quyết đị nh đư a vào toàn bộ chương trình m ột ki ểu đặt t ên kì l ạ (a Flinstones naming theme), kh ông ph ải t ôi đù a đâu. Cách bạn đặt tên bi ến và hàm l à trung tâm củ a việc xây dự ng m ột chương trình dễ đọ c. Có nhi ều lập trì nh viên ph ạm lỗi khi đặ t tên bi ến và h àm m à n ó: quá dài hoặc qu á ng ắn  kh ông li ên quan đến ng ữ cảnh  kh ông để ý đến cách-viết-phân-bi ệt (case sensitivity)  ngăn cản kh ả năng dễ đọ c ( đặc bi ệt l à các h àm)  1. Đặ t t ên bi ến 1.1. C ách viết ph ân bi ệt Trong PHP, tên bi ến có cách vi ết ph ân bi ệt, ngh ĩ a l à $user và $User l à hoàn toàn kh ác nhau. Vài ng ười dù ng l ợi dụng đi ểm này để đặt các bi ên cù ng tên nh ư ng kh ác cách viết. Đâ y l à m ột thó i quen tồi tệ. Cách vi ết kh ông bao gi ờ n ên d ùng để ph ân bi ệt các bi ến kh ác nhau. Mỗi tên bi ến, trong cùng tầm vự c (scope), nên có là tuyệt đối duy nh ất. 1.2. Tên qu á ng ắn Nhi ều ng ười sử dụ ng nh ữ ng ch ữ vi ết tắt đầu (cryptic acronym) bí ẩn cho các bi ến của họ, để rồi sau này h ối tiếc vì qu ên m ất họ đã mu ốn ám chỉ đi ều gì khi đó . Tên bi ến n ên m ô tả n ội dung n ó (sẽ) chứ a, dù ng nguy ên từ hoặc nh ữ ng ch ữ vi ết t ắt có thể hi ểu được. 1.3. Tên qu á d ài Ở kh í a cạnh kh ác, vài ng ười l ại sử d ụng tên bi ến qu á dài. Nói chung, tên bi ến kh ông nên dài quá hai từ . Hai từ có thể được tách bi ệt bằng dấu ph ân cách "_" hoặc l à vi ết hoa ch ữ đầ u của từ thứ hai. 1.4. Th ói quen tốt Dưới đây l à nh ững thí dụ t ốt về tên bi ến $username = 'phanthanhkieu'; $password = 'bimat'; $teachers = array ('Sadlon', 'Lane', 'Patterson', 'Perry', 'Sandler', 'Mendick', 'Zung'); foreach ($teachers as $teacher); 10 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  11. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes 1.5. Th ói quen xấu Dưới đây l à nh ững thí dụ (ph óng đại) về nh ữ ng tên bi ến t ồi $username_cua_csdl= 'SINHVIEN'; $guMbi = 'bimat'; // for the $password $tentruocdo_cua_giaovien = array ('Sadlon', 'Lane', 'Patterson', 'Perry', 'Sandler', 'Mendick', 'Zung'); foreach ($tentruocdo_cua_giaovien as $TeaChER); 2. Đặ t t ên h àm Mọi kh ái ni ệm áp dụng cho t ên bi ến cũng áp dụ ng cho đặt tên h àm. Tuy nhi ên, ng ữ ph áp đóng vai trò đặc bi ệt trong các hàm. Các hàm PHP, đị nh ngh ĩ a sẵn ho ặc do người d ùng đị nh ngh ĩ a, l à kh ông-ph ân-biệt-cách- vi ết (not case sensitive) 2.1. Dù ng độ ng từ Hàm củ a PHP t ương đương với m ột độ ng từ khi n ói. Tên hàm, do đó, n ên được hướng hành động (action oriented). Nó cũng n ên được dù ng ở thì hi ện tại. Thí dụ, bạn có m ột h àm tạo m ột số ng ẫu nhi ên với ph ân bố Gausse (a gaussian random number), b ạn nên đặ t tên nó l à generate_gaussian_rand(). Ch ú ý các sử d ụng động từ hành động trong tên h àm. Nó sẽ đặt h àm vào ngữ cảnh thí ch hợ p Để so sánh, h ãy xem thí dụ: Bạn có thấy sự kh ác bi ệt? Thí dụ thứ hai sử dụ ng danh từ , m ặc dù vẫn chuy ển tải được m ục tiêu của h àm, nh ư ng n ó ng ăn ng ười ta đọ c m ột cách trôi chảy. Hãy sử dụ ng độ ng từ ! 13. Kh ông suy ngh ĩ thấu đáo: CSDL & SQL Số cách người ta truy cập cơ sở dữ li ệu (CSDL - database) và lấy kết qu ả nhi ều đến m ức thự c sự ng ạc nhi ên. Nh ữ ng thí d ụ t ôi đã gặp bao gồm nh ữ ng tổ h ợp l ệnh if và vòng l ặp do.. while, các câu gọi nhi ều l ần, và các hàm sql_result() trong vò ng for. Nh ững người này có ngh ĩ họ đang l àm g ì kh ông? Vi ệc vi ết các m ã trật-hoặc-trú ng (hit-or-miss code) ch ứ ng minh sự thi ếu tập trung. Nh ữ ng cá nh ân đó xác đị nh nỗ l ự c của h ọ dù ng để hoàn thành công việc hơ n l à để ho àn thành đú ng công việc, kết qu ả là l àm cho các ông chủ qu ăng thời gian và tiền b ạc ra đường. 11 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  12. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes Sự l ấy m ẫu kh ông ch ính xác là m ộ t thí dụ hay về vấn đề này. Vài ng ười viết lệnh kh ông dành thờ i gian để ngh ĩ thấu đáo. Đú ng l à kh ông ch ỉ có duy nh ất m ộ t cách “đú ng ” để l ấy m ẫu dữ li ệu, nh ư ng n ó có r ất nhi ều cách kh ông đú ng. Ph ần này bao gồm các ch ủ đề:  Áp dụ ng sai các hàm về CSDL  Dùng sai SQL: kh ông lấy nh ữ ng thứ b ạn cần  Dùng PHP để sắp xếp kết qu ả 1. Dùng sai các hàm CSDL Một đoạn m ã PHP đã d ùng cú ph áp sau để l ấy kết qu ả t ừ CSDL (presented below using a generalized set of SQL functions): if (!($mautin = sql_fetch_row ($truyvan))) { print "Mot loi xay ra: Khong tim thay mau tin nao!"; exit; } do { print "$mautin[0]: $mautin[1]\n\n"; } while ($mautin = sql_fetch_row ($truyvan)); Chú ý: Ở trên, và các thí dụ sau nữ a, $truyvan di ễn tả handle ho ặc pointer đến m ột tập kết qu ả truy vấn.. Nó i cách kh ác, m ột truy vấn đã được gử i và m ột tập kết qu ả đã được trả về. Các thí dụ sẽ nó i về vấn đề thao với với kết qu ả trả về. Có m ột vài vấn đề với đoạn m ã trên:  Nó ki ểm tra các trường h ợp “kh ông tì m thấy” ("no incidents" case) bằng cách l ấy m ột dòng  Nó kh ông lư u kết qu ả vào m ảng li ên kết (associative array) 1.1. Ki ểm tra trường hợp kh ông tì m th ấy: cách l àm sai Bằng cách d ùng sql_f etch_row(), PHP chủ trương m ột cách tiếp cận h àm ẩn cho việc xác đị nh có kết qu ả tì m thấy hay kh ông. Mộ t cách kh ác trực tiếp và tường minh l à đếm số d òng của kết qu ả b ằng sql_num_rows() nh ư dưới đây: 1.2. Từ bỏ vòng lặp Do..While Trước hết và trên h ết, vòng lặp thô tụ c do..while kh ông bao gi ờ cần n ữ a vì khi dù ng sql_num_row(), ch úng ta kh ông ph ải lấy dòng đầu tiên củ a kết qu ả khi mu ốn ki ểm tra kết qu ả trống. Thí dụ cũ đã di ễn tả m ột thí d ụ m à trong đó, n ếu kết qu ả kh ông r ỗng, dòng đầ u tiên đã được l ấy bằng hàm sql_f etch_row() trong câu l ệnh if. C ấu trú c do..while cần thi ết trong trường hợ p này vì khi đó, bộ đế m củ a CSDL đã tăng l ên và chuy ển sang d òng kế tiếp. Do đó, bạn ph ải xử l í (l ệnh do)dòng đầu tiên vì nó đã được lấy. Các lệnh tiếp theo l ấy các dòng kế, và cứ thế. 12 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  13. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes Tại sao vòng do..while bị coi nh ư thô tụ c, xấu xa (nasty)?  Trong thí dụ trên, ch ỉ có 1 l ệnh in kết quả trong vòng l ặp. Hãy tưởng tượng, nếu có 10 lệnh, ng ười đọc mã ph ải tì m đi ều ki ện while sau các câu lệnh đó . Một công vi ệc phi ền toái. Điều ki ện While b ắt đầ u cấu trúc thường xuy ên h ơn l à kết thúc. M ột nh à nghi ên  cứ u sẽ ph ải cẩn thận hơn để kh ông nhầm lẫn đi ều ki ện while cu ối với đi ều ki ện while đầ u. 1.3. Giữ mọi th ứ g ọn gàng v à đơ n gi ản Với trường hợp kết qu ả r ỗng, sql_num_rows() đư a đế n ngay kết qu ả, trong khi sql_f etch_row() thì kh ông sql_fetch_row() n ói r ằng "Tôi tì m thấy 0 d òng trong tập kết qu ả. Đi ều n ày  ngh ĩ a l à có 0 kết qu ả” (I found no rows in the result set. This must mean that there are none.) sql_num_rows() nói r ằng “Số d òng trong kết quả l à 0” (The number of rows in  the result set is 0). Nh ưng đi ều đó thực sự t ạo n ên sự kh ác bi ệt n ào? Xét cùng m ột sự so sánh, nh ư ng bây gi ờ là trong ng ữ cảnh của đi ều ki ện if và của bi ểu thứ c, trong đ oạn l ệnh gi ả (Pseudo-code): * if(!($mautin = sql_fetch_row($truyvan))) { Print Error }: o l ấy 1 d òng trong tập kết quả o nếu kết qu ả rỗng, gán cho $mautin gi á trị zero (0); 0 có gi á trị logic l à False, do đó !(0) = True; in thông báo l ỗi. o nếu kh ông r ỗng, l ấy dòng đầu tiên và g án nó vào $mautin; $mautin kh ông ph ải l à zero và có gi á trị l à True. Do đó !(True) = False, và tiếp t ục với cấu trú c do..while. * if((sql_num_rows($truyvan)
  14. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes 1.4. Khi mà DBMS củ a b ạn kh ông h ỗ trợ sql_num _row() Vài DBMS có thể kh ông hỗ trợ hàm sql_num_row(). T ôi xin chia sẻ với b ạn n ếu DBMS của bạn là m ột trong số đó. Bạn sẽ ph ải tì m trong kết quả r ỗng b ằng cách l ấy d òng. Tuy nhi ên, trong trường hợp n ày, n ó n ên dù ng m ột bi ến boolean nh ư sau: 1.5. L ấy kết qu ả: hãy ch ọn cách có í ch Vấn đề thứ hai trong đoạn m ã này l à n ó d ùng sql_f etch_row() để l ấy t ập kết qu ả. Hàm sql_f etch_row() ch ỉ trả về m ảng đánh chỉ số, trong khi đó sql_f etch_array() trả về m ảng đánh chỉ số và m ảng d ùng chuỗ i. $mautin = sql_fetch_array ($truyvan); print $mautin[1]; // Cot thu 2 print $mautin[name]; // Ten cot Chú ý : C ó nhi ều quy ước kh ác nhau về vi ệc d ùng dấu nh áy khi thêm một đối số ki ểu chu ỗi. Trong thí dụ về t ên cột ở trên, và suốt b ài vi ết n ày, n ó sẽ được bỏ. Từ quan đ iểm của nh à ph át tri ển, hàm nào có l ợi hơ n? Mảng d ùng chu ỗi gi ú p cho ng ười đọc hi ểu được bạn đ ang l ấy cái gì ch ỉ thông qua việc đọc m ã, nh ư thí dụ đú ng d ưới đây: 1.6. Khi n ào sql_f etch_row($truyvan) n ên đượ c d ùng Tôi kh ông thực sự là fan của the sql_f etch_row(). Tuy nhi ên, có m ột tì nh hu ống m à d ùng nó kh ông gi ảm kh ả năng dễ đọc: khi ng ười d ùng đị nh ngh ĩ a câu truy vấn. Các thí dụ cho đế n lú c n ày đề u đề cập đế n nh ững câu truy vấn được bi ết trước. Đô i khi bạn để cho người d ùng tự đị nh ngh ĩ a câu truy vấn. Trường hợp này bạn sẽ kh ông bi ết các cột trong kết qu ả. Do đó, dù ng hàm sql_f etch_row() kèm với count() sẽ xử l í hi ệu qu ả các cột trong m ột hàng: 2. Dùng sai SQL: kh ô ng lấy nh ững gì b ạn cần 14 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  15. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes Nh ư l à vấn đề củ a thự c h ành, đơn gi ản l à sẽ sai lầm khi dù ng PHP xử l í m ọi dòng củ a CSDL. Tôi đã b ắt gặp ng ười ta d ùng PHP để ch ạy m ột ch ương trì nh tìm ki ếm đơ n gi ản trên 2MB dữ li ệu và tự hỏi tại sao cái ngôn ngữ này chạy l âu thế. Lấy 2MB dữ li ệu từ CSDL có thể l àm bạn ch ờ m ãi m ãi. Ng ôn ng ữ truy vấn chuẩn (Standard Query Language - SQL ) đượ c thi ết kế đặc bi ệt để truy vấn và l ấy dữ li ệu từ các bảng của bạn. Ý tưởng l à dù ng n ó để l ọc d ữ li ệu kh ông cần thi ết, để l ại các thông tin li ên quan cho PHP xử l í . Nếu bạn l ấy nhi ều dữ li ệu hơn cần thiết, đó l à dấu hi ệu ch ắc chắn r ằng m ã SQL đ ang dù ng ch ưa được tối ưu ho á. 2.1. M ệnh đề WHERE Một thí d ụ kinh đi ển về sự hi ểu qu ả củ a SQL li ên quan đến m ệnh đề where. Đoạn m ã sau sẽ l ấy các kết qu ả và in ra tên và m ã sinh vi ên của sinh vi ên có MASV='511203008': Đoạn m ã trên ch ư a đượ c t ối ư u: chú ng ta đ ang d ùng PHP để t ìm ki ếm trong toàn b ộ CSDL! Nếu như đi ều n ày kh ông quan trọng đố i với các CSDL nhỏ , khi kí ch thước CSDL t ăng l ên bạn sẽ cảm thấy m ột cú đấm nặng nề về hi ệu năng. Lờ i gi ải r ất đơn gi ản: sửa câu SQL để chứ a m ệnh đề WHERE: $strsql = "SELECT * FROM SINHVIEN"; $strsql .= " WHERE MASV='511203008'"; 15 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  16. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes Mệnh đề WHERE cho ph ép b ạn tì m ki ếm chọn l ọc hơ n. Gi ới hạn ch ọn l ọc củ a m ệnh đề where chí nh l à m ột hàm với đối số củ a n ó. Trong thí dụ trên đố i số là " MASV='511203008'". Bây gi ờ ch úng ta đã chọn được dữ li ệu cần thi ết, b ạn chỉ việc dù ng PHP để in ra sau đó: if (@sql_num_rows ($truyvan) != 1) { die ("Khong dung so mau tin nhan duoc tu CSDL!"); } $mautin = @sql_fetch_array ($truyvan); print "Ho va ten: $mautin[HOTEN]\n\n"; print "MASV: $mautin[MASV]\n\n"; 3. Dùng PHP sắp xếp kết qu ả Nhi ều ng ười l ấy d ữ li ệu ở t ình trạng kh ông có thứ tự , như ng rồi đoạn m ã PHP tiếp theo l ại sắp thứ tự chú ng. Nên chớ r ằng sắp xếp bằng SQL nhanh hơ n PHP. Dù ng cú ph áp ORDER BY củ a SQL để sắp xếp thay vì h àm ksort() củ a PHP. Thí dụ dưới đây dù ng ksort() để sắp xếp theo tên: $strsql = "SELECT name, email, phone FROM some_table "; $strsql .= "WHERE name IS LIKE '%baggins'"; $truyvan = @sql_db_query ($strsql, "samp_db", $ketnoi); if (!$truyvan) { die (sprintf ("Error [%d]: %s", sql_errno (),sql_error ())); } while ($mautin = @sql_fetch_array $truyvan)){ $matches[$mautin[name]] = array ($mautin[email], $mautin[phone]); } ksort ($matches); Nh ưng tại sao kh ông sắp xếp dữ li ệu ngay vào lú c nó được đị nh ngh ĩ a? Nó gi úp chú ng ta đỡ ph ải duy ệt qua tập kết qu ả lần thứ hai. Do vậy, b ỏ h àm ksort() ra kh ỏi ch ương trì nh trên và thay đoạn m ã SQL bằng đoạn d ưới đây, có d ùng dùng cú ph áp ORDER BY: $strsql = "SELECT name, email, phone FROM some_table "; $strsql .= "WHERE name IS LIKE '%baggins' ORDER BY name"; 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 để: 16 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  17. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes  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. 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. 1.2. Ki ểm tra kết qu ả l ời gọ i hệ thống 17 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  18. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes 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. $ketnoi = @sql_connect ($host, $user, $pass); if (!$ketnoi) { 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 ả. 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 functio n). 18 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  19. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes 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. 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: 19 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
  20. PHP programming dynamic web for ewreybody 21 Fatal errors in programming with PHP – Collect from writ ting of Sterling Hughes  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 AP I Á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 CalcMortgage.php 20 NGUYEN ANH KHOA– Class 27K0A – DepartmentOf Information Technology Dormitory 204.B5 18:20 PM April 7, 2006
nguon tai.lieu . vn