1. Trang chủ
  2. » Công Nghệ Thông Tin

Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP tập 2 phần 2 nguyễn minh, lương phúc

133 292 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 133
Dung lượng 2,35 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Mọi đối tượng Exception đều chứa th êm một sô’ th ô n g tin m à có th ể được sử dụng cho việc gỡ rối nguồn của ỉỗi... Dù vậy, thực t ế phương p háp dựa vào ngoại lệ n ày tin h vi hơn nhi

Trang 2

ngưdi đ ã p h á t triể n ít có k in h nghiệm hơn là m ột chương trìn h "tốt” là m ột chương trìn h làm việc k h ô n g có lỗi Thực

tế, điều n ày không h o àn to àn đúng: Một đ ịn h n g h ĩa rõ h ơ n có th ể là một chương trìn h dự đoán trước tâ't cả điều kiện lôi có th ể có v à g iả i quyết chúng

m ột cách n h ấ t quán và ch ín h xác

Viết các chương trìn h "thông m inh" tu â n theo đ ịn h n g h ĩa n ày là m ột đòi

hỏi nghệ th u ậ t cũng như kỹ năng K inh n g h iệm và tr í tưởng tượng đóng

m ột vai trò quan trọ n g cho việc đ án h giá nhữ ng nguyên n h â n gây lỗi tiềm

Trang 3

án v à d ịn h n g h ĩa h à n h động hiệu chỉnh nhưng không k ém p h ầ n quan trọ n g hơn là b ản th â n ngôn ngữ lập trìn h d ịn h nghĩa nhữ ng công cụ v à chức nàn g

có sẵ n để bẫy v à giải quyết các lỗi

T h ậ t m ay th a y , P H P giỏi về lĩnh vực này; ngôn ngữ n ày có m ột fram e-

w ork tín h vi để giúp các n h à p h á t triể n đón b ắ t các lỗi và có h à n h động sửa chữa Chương n ày sẽ giới th iệu bạn về framework này, tr ìn h bày cho b ạn về

mô h ìn h ngoại lệ P H P 5.3 v à hướng dẫn bạn cách tạ o các thường tr ìn h xử

lý lỗi được tùy b iế n theo những nhu cầu của ứng dụng PHP

Xử lý các lỗi S crip t

N hư bạn đã là m việc qua những đự án tro n g sách này, chắc ch ắn b ạ n sẽ gặp m ột vài sự cố; M ột dấu ngoặc được đ ặ t sai chỗ ở đây, th iếu m ột dấu chấm p hẩy ở đó; có lẽ m ột h à m được gọi ra nhầm ở nơi k h ác nào đó Và bạn

sẽ chú ý ră n g P H P thực sự r ấ t giỏi về việc chỉ r a rõ n h ữ n g lỗi này Trong trường hợp P H P tạ o m ột th ô n g báo lỗi nhưng tiếp tục thực th i script; trong

nh ữ n g trường hợp khác nghiêm trọ n g hơn, nó tạ m dừng việc thực th i script

b ằn g m ột th ô n g báo chỉ đ ịn h số dòng đã gây ra lỗi

Loại lỗi vừa được mô tả là các lỗi cấp "script"; chúng xảy ra k h i bộ máy

P H P gặp p h ả i n h ữ n g khiếm khuyết trong cú ph áp hoặc cấu trúc của một

PH P C húng chỉ thư ờng n h ậ n th ấ y được một k h i P H P thực sự b á t đầu p h ân tíc h v à thực th i m ộ t script Để m inh họa, hăy thử tạo v à chạy sc rip t sau dây:

Đầu r a của sc rip t này trô n g giông như h ìn h 10.1

N hư h ìn h 10.1 m in h họa, script này đã tạo h a i loại lỗi: m ột "cảnh báo" (w arning) về nỗ lực chia cho zero, và "lỗi nghiêm trọng" (fata error) về nỗ iực gọi r a m ột h àm k h ô n g xác định Thực tế các lỗi P H P có th ể được p h ân loại rộ n g th à n h b a h ạ n g mục chính như được liệt kê tro n g b ản g 10.1

Có m ộ t sự p h â n cấp rõ rà n g cho các thông báo lỗi của PH P: các thông báo (notice) í t n g h iê m trọ n g hơn các cảnh báo (vvarning) m à lầ n lượt ít

ng h iêm trọ n g h ơ n các lỗi nghiêm trọ n g (fatal error) Theo m ặc đ ịn h PH P

C h ư d n g 10: x ử lý c á c lỗi 1 5 7

Trang 4

1 5 8 C h ư ơ n g 10: x ử lý các lỗi

chỉ h iể n th ị các cảnh báo và lỗi nghiêm trọ n g tro n g đầu r a sc rip t (m ặc dù như b ạn sẽ th ấ y ngay sau đó, bạn có th ể th a y đổi h à n h vi m ặc đ ịn h n ày sao cho th ậ m chí các th ô n g báo chỉ n h ìn th ấ y được tro n g đầu r a script) Các Ỉ5i

có th ể xảy r a tạ i các giai đoạn khác nh au tro n g vòng đời của m ột sc rip t - lúc khởi động, vào thờ i gian p h ân tích, vào thờ i gian biên dịch hoặc vào thời gian chạy - và do dó P H P cũng đưa ra những k h ác b iệ t nội tạ i về nhữ ng giai đoạn khác n h au này Nói chung, tổng cộng là 12 cấp lỗi kháo n h au (cộng với

h ai cấp "đặc biệt") được tượng trưng b ằn g các h ằ n g có tê n M ột d a n h sách hoàn ch ỉn h các cáp lỗi n ày có th ể tìm th ấ y tạ i w w w php.neưm anuai/eĩi/' ref.errorfunc,php#errorfunc.constants B ảng 10.2 liệ t k ê các cấp lỗi m à bạn

sô thường sử dụng n h ấ t

H ầu h ế t nhừ ng câp lỗi n ày dễ hiểu Các cấp lỗi m à có lẽ b a n gặp trụ c trặ c

là các cấp lỗi E_ƯSER được đ ặ t sang m ột bên d àn h cho các lỗi cấp ứng dụng t'jy ỹ Đừng bận tâ m về nhữ ng cá'p lỗi này vì p h ầ n iđn chúnịỊ có dược th ay

th ế bdi mô h ìn h ngoại lộ mới được giới th iệu tro n g P H P 5

M ô t ả

Các lỗi không quan

t r ọ n g k h ô n g n g á n

P H P th ự c t h i m ộ t script

V í d ụ

Truy cập một biến dã không được khởi tạo

Các cảnh báo (warn-

ing)

Các lỗi nghiêm trọng

h ơ n đ ò i h ỏ i chú ý nhimg vẫn không dừng việc thực th i sc rip t (mặc dù một số phần của script có thể hoạt động không chính xác)

Đọc m ộ t file k h ô n g

h iện hữu trong đường dẫn được nêu rõ

Trang 5

th i một script

Thể hiện cụ th ể một đô’i tư ợ n g cù a m ộ t class không xác định

M ô tả

Các lỗi phân tích (parse) nghiêm trọngCác lỗi thời gian chạy (thông báo) không nghiêm trọng

Các lỗi thời gian chạy (cảnh báo) không quan trọng

Các lỗi thời gian chạy nghiêm trọng buộc kết thúc script

Các lỗi ứng dụng (thông báo) không nghiêm trọng do người dùng ấn định

Các lỗi ứng dụng (cảnh báo) không nghiêm trọng do người dùng ấn định

Các lỗi ứng dụng nghiêm trọng do người dùng

ấn dịnhCác lỗi thời gian chạy không nghiêm trọng nảy sinh từ cú pháp PH P thừa kêVkhông được

tá n thànhTất cả lỗi

Bảng 10.2 Các cấp lỗi PHP

Điều khiển v iệ c báo cáo lỗi

B ạn có th ể điều k h iể n các lỗi nào dược hiển th ị tro n g đầu r a sc rip t bằng

m ột hàm P H P cài sẵ n dược gọi là errQr^reportingO, H àm này chấp n h ận

m ột hoặc nhiều h ằ n g được đ ạ t tên từ b áng 10.2 và yêu cầu sc rip t báo cáo các iỗi khớp với các lỗi đó Tuy nhiên, có m ột ngoại lệ: việc chuyển các lỗi CE_PARSE) n ảy s in h từ n hữ ng khiếm khuyết cú pháp tro n g m ột scrip t PH P không th ể được ẩ n sử dụng hàm error_reporting(),

Để th ấ y trực tiế p điều này, xem xét b ản v iết lại sau đây của m ột trong các scrip t trước đó để "làm ẩn" các lỗi không nghiêm trọ n g

<?php

// only đisplay fatal errors

error_reporting {E_ERROR);

Trang 6

Hỏi chuyên gia

H ỏ i: C ấ p lỗi £ _ S T R IC T làm đ iẻ u gi?

Đáp: Tại cấp lỗi E _ S T R I C T , PHP kiểm tra mã vào thời gian chạy và tự động lạo các đề xuất vể cách nó có tnể đưọc cải tiến nhu thế nào s ử

d ụ n g E S T R I C T I h ư ờ n a c ó th ể tnộ t b á o đ ộ i ì g v ổ rihữniạ h à in m à s ẽ bi

h ỏ n g trcng tnôt p hièn bản tương lai c ủ a PHP v à v iệ c sử d ụ n g PÓ dưỢc

đ ề n g h ị đ ể c ả i t h iệ n k h ả n ă n g b ả o trl m ã t r o n g th ờ i h ạ n d à i.

nghiêm trọ n g vào th ờ i gian chạy n h ư trong ví dụ sau đâ>:

m ột loại n h ấ t đ ịn h M ặc dù scrip t trước sẽ khòng h iể n th ị m ột th ô n g báo lỗi

n h ìn th ấ y được, n h ư n g nó sẽ vẫn tạo r a m ộ t lỗi nghiêm trọ n g v à việc thực

th i sc rip t sẽ v ẫn dừng tạ i điểm lỗi

B ạn cũng cố th ể chuyển đến error_reporting() m ột tổ hợp các cấp lỗi để tùy biến hệ th ô n g báo cáo lỗi của P H P th ậ m chí x a hơn Ví dụ, xem xét scrip t sau đây, sc rip t n ày chỉ báo cáo các th ô n g báo v à lỗi nghiêm trọ n g nhưng không p h ả i là các cảnh báo:

Trang 7

C h ư d n g 1 0 ; x ử lý các lỗi _ _161

echo someFunc(); / / íatal

?>

Cũng có th ể t ắ t chức n ăn g báo cáo lỗi một cách có chọn lọc, tr ê n cơ sở

m ỗi h àm b ằng việc b ắ t đầu lệ n h gọi h àm bằng to á n tử Ví dụ, đoạn m ã sau đây thường tạo r a m ột lỗi nghiêm trọ n g bởi vì som eFunction() không

th i sc rip t (nếu lỗi n g h iêm trọng) Thông báo được tạo r a bdi phương thức xử

lý lỗi sử dụng m ột khuôn m ẫu (tem plate) chuẩn: nó chỉ d ịn h loại lỗi, lý do cho lo ại lỗi, và tê n file v à số dòng nơi lồi đã được tạ o (xem h ìn h 10.1 để

th â y m ột ví dụ)

Tuy nhiên, k h i các ứng dụng P H P ngày càng trở n ê n phức tạ p hơn, cơ câu xử lý lỗi mặc đ ịn h n ày rố t cuộc thường khong th ỏ a đ án g Ví dụ có th ể

b ạn m uôn tùy biến te m p la te được sử dụng bởi phương thức xử lý lôi dể hiển

th ị n h iề u hoặc í t th ô n g tin hcfn hoặc có th ể b ạn m uốn g h i n h ậ t ký lỗi sang

m ột íĩle hoặc cơ sở dữ liệu th a y vì hiển th ị nó cho người dùng Đối với t ấ t cả tìn h huông này, P H P đưa r a h àm set_error_handler(), h à m n ày cho phép

b ạn th a y th ế phương thức xử lý lỗi cài sẵn của P H P b ằ n g phương thức xử lý lỗi r iê n g của bạn

Trang 8

H àm set_error_handler() chấp n h ậ n m ột đối số: tê n của h àm do người

dùng định n g h ĩa m à sẽ được gọi r a k h i m ộ t lỗi xảy ra H àm tù y ý n ày phải

có k h ả nỗLng chấp n h ậ n tố i th iể u h a i đối sô' b ấ t buộc (loại lỗi v à th ô n g báo

mô tả tương ứng) và lên đến th ê m b a dối sô' (tê n file, sô' d òng nơi lỗi đ ã xảy

ra, v à m ột sự k ế t xu ất không gian biến vào th ờ i gian lỗi)

-1 6 2 C h ư ớ n g -10: x ử lý các lỗi

M ộ t p h ư ơ n g th ứ c x ử lý lỗ i tù y ý k h ô n g th ế c h ặ n c ấ c ỉỗ i n g h iê m trọ n g (E _ E R R O R ), c á c lỗ i p h â n tíc h (E _ P A R S E ), h o ặ c c á c th ô n g

b á o m ã th ừ a k ế (E _ S T R IC T ).

Đê’ m in h h ọ a diều này, hãy xem x é t ví dụ sau đây:

ở dây m ột h àm xử lý lôi do người dùng đ ịn h n g h ĩa th a y t h ế phương thức

xử 1>' (handler) cài sẵii uủa PK P, tạ o động m ột tra n g lỗi tù y ý.

<!D0CTVPE html PUBLIC "-.//W3C//DTD XHTiVIL 1,0

color: purple;

)

,warning { font*weight; bolđer;

Trang 9

C h U ớ n g 1 0 : x ử lý c á c lỗi _ 1 6 3

se t_error_handler{‘m yH andler’);

/ / report ail errors

error_reporting{E _A LL);

/ / generate some errors

echo $var; / / notice

echo 23/0; / / warning

/ / custom error handler

íunction m yHandler($type, $m sg, $file, $íine, Scontext) I

$ text = “ An error occurred on line $line while Processing your request,<p>

Please visií our <a href=http://www.dom ain.dom >hom e page</a>

and try again,";

sw itch{$type) I case E.NOTICE:

echo “ <div class=\” notice\” >$text</điv><p>";

ở đây h à m se t_ erro r_ h an d ler() tự động chuyển hướng t ấ t cả lỗi sang

h à m do người dùng đ ịn h n g h ĩa myHandlerO- K hi m ột lôi xảy ra , h àm này được chuyển loại lỏi, th ô n g báo lỗi, file v à số dòng nơi lỗi đ â xảy r a cùng với ngữ cản h k h ả b iến Sau đó nó h iể n th ị m ột tran g lỗi tù y ý chứa số dòng của lỗi b ằ n g m àu tía (các th ô n g báo) hoặc m àu đỏ (các c ả n h báo), v à tạ m đừng

b ằ n g ta y việc thự c th i scrip t H ìn h 10.2 m inh họa k ế t quả

Trang 10

Kình 10.2 Một trang lỗi được tạo ra bồi mộỉ phưđng thức xử lý lỗi tùy ý

Hỏi chuyên gia

H ỏ i: Làrn tn ế n â o tò i p h ụ c hồi c ơ cãu x ử lý lố i m ặ c đ ịn h c ủ a P H P rr.ộ t kh i

tõ i đ à gọi s e t_ e rro r_ h a n d !e r() ?

Đ á p : C ó hai c á c h đ ể làm đ ié u n à y P h ư ơ n g p h á p đơn g iả n n h á t là sử d ụ n g hàm re s to re _ e rro r_ h a n d ie r() c u a P H P H àm n à y p h ụ c h ồ i p h ư ơ n g th ứ c

x ử lý lỏi sau c ù n g đ a n g s ử d ụ n g trư ớc kh i s e t_ e rro r_ h a n d le r() đ ư ợ c gọi,

T ro n g hẩu h ế t c á c trư ờ n g h ợ p , đ â y s ẽ là p h ư ơ n g th ứ c x ử lý lỗi m ặ c định

và sẽ th a y th ế m ột ví dụ tro n g p h ầ n "ghi n h ậ t ký" m ộ t lỗi,

Thực hành 10.1: Tạo m ột tra n g lỗi sạch

Phương thức xử lý lỗi mặc đ ịn h của P H P chỉ h iể n th ị th ô n g tin về m ột lỗi Thông báo lỗi n ày thường x u ất h iệ n tro n g k h i m ộ t tr a n g đầu r a đang được tạo, p h á vỡ việc sắ p đ ặ t (layout) tr a n g và gây r a sự n h ầ m lẫ n v à sự căng th ẳ n g người dùng không cần th iế t (xem h ìn h 10.3 để th ấ y m ột ví dụ

về m ột tra n g n hư vậy) Tuy n h iê n , bằn g việc th a y th ế phương thức xử lý lỗi

m ặc đ ịn h b ằn g m ột h à m tù y ý, b ạ n có th ể dễ d àn g g iả i q u y ết v ấn đề này bằng việc tạo m ột tr a n g lỗi "sạch" khác tro n g k h i đồng th ờ i g h i n h ậ t ký các lồi sc rip t sang m ột cơ sở dữ liệu đ ể xem lạ i sau đó Ví dụ tiế p theo th eo sau đây sè hướng d ẫn b ạ n cách làm điều này

Trang 11

C h ư ơ n g 10: x ử lý các lỗi 1 6 5

Đ ể b ắ t đầu, tạ o m ột cơ sở dữ liệu SQLite mới, v à m ột b ả n g để chứa thông tin lỗi như được m in h họa ở đây:

shell> s q lite app.db

sqíite> CREATE TABLE errors (

„ > id INTEGER PRIMARY KEY, > date TEXT NOT NULL,

„ > e rro r TEXT NOT NULL, > s c rip t TEXT NOT NULL, > lin e TEXT NOT NULL .> ):

T iếp theo đ ịn h n g h ĩa m ột phương thức xử lý lỗi tù y ý ch ặn t ấ t cả lỗi

sc rip t và ghi chúng sang bản g này sử đụng PDO n h ư tro n g sc rip t sau dây (app.php):

Hello and welcoiiie to thỉs page.

W an ù n g inclu<de(missmg51 c.php) ffiricbờn mdude] faile J to open 5trcam: N o 5 uch file or

diectỡcyư) C :\P rosraỉn FiJe$\ỉntemet

W a n d n g ư i th iđ p ũ ÍB-mcticm m d u d e l P ôilcd op^ĩmig ’ni' 5 suìg 61 e p h p ' f o r ứỉcluM ộn

Trang 12

1 6 6 C h ư ơ n g 1 0 : X ử lý c á c lỗi

ob_start();

/ / detine a cusíom handler

/ / vvhich logs errors to the database

/ / then generates an error page

íunction m yHanđler($type, $msg, $file, $line $context) {

/ / log error to database

$date = $pcio->quote(date('cl-M-Y h;i;s’, mKtimeO)):

$sql = “ INSERTINTO errors {đate, error, script, line) VALUES {Sđate $msg

$file, $line)";

$pđo->exec{$sql);

// reset and close the output buffer

n generate a new error page

Trang 13

/ / oưtput some page text

echo "<h1>Hello and vvelcome to th is page.</h1>";

/ / generate vvarning (íile noí found)

Trang 14

Các h à m điều k h iể n đầu r a của P H P làm việc b ằng cách chuyển hướng

t ấ t cả đầu r a dược tạo bdi m ột sc rip t sang m ột bộ đệm đầu r a (output buíTer)

đ ặ c b i ệ t tr o n g bộ n h ớ t h a y v ì gởi n ó trực tiế p s a n g t r ì n h d u y ệ t C lient Nội dung của bộ đệm này vẫn n ằ m tro n g bộ n h ớ cho dến k h i chúng được làm cho n h ìn th ấ y được đối với người dùng một cách tường m inh H oặc chúng có

th ể bị xóa đơn giản b ằn g việc xác lập lại bộ đệm

Có b a h à m chính đ ể học về API điều khiểr, đầi: ra của PH P:

K Hàm ob_start() khởi lạo một bộ đệm đầu ra va chuẩn t)ị nó đ ê chặn idệc X ì iấ t một script Không cản p h ả i nói bàm này nên đĩcạc gọi intôc hhi hất kỳ iíii/ ra được tạo bồi scripi.

m H àm ob_cndJĩushO kết thúc việc đệm đầu ra (onípul biiffcring) và gởi nội đung hiện hành cứa bộ đệìu đầu ra sang thiết bị đẩu ra Ohường là trình duyệt của ngKòi dùng).

• ỉ ỉ à m o b _ c n d íic a u C kổĩ ihúc viộc đ ệ m đâu ra , ’à là m scỊCi' n ộ i dìDĩiĩ

hiộn hãnh của bộ đệm đầíi ra.

Sau k h i ghi nhớ lý th u y ế t này, hăy quay trở lại sc rip t trước đ ể th ấ y các

bộ đệm đầu r a có th ể giúp tạo các tra n g lỗi sạch hơn như th ế nào N hìn

th o á n g qua sc rip t n ày v à bạn sẽ th ấ y rằ n g nó b ắ t đầu b àn g việc khởi tạo

m ột bộ đệm đầu r a mới b ằn g ob_start() v à m ột phương thức xử iý lỗi tùy ý với set_ erro r_ h an d ler() B ất kỳ đầu ra được tạ o r a bởi sc rip t bây giờ sẽ được lưu tr ừ tro n g bộ đệm đầu r a cho đến khi nó được giải phóng sa n g C lient

b ằ n g cách gọi đ ến ob_end_flush()

B ây giờ h ãy xem x ét những gì xảy r a k h i m ột lỗi x u ất h iệ n tro n g script

Đ ầu tiê n phương thức xử lý lỗi tùy ý sẽ ch ặn lỗi nàv, m ở m ột h a n d le PDO

d ẫ n đ ến íile cơ sở dữ liệu SQLite được tạo ở bước trước v à chuyển đổi lỗi (th ô n g báo hoặc cảnh báo) th à n h m ột query SQL INSERT Sau đó query

n ày sẽ được sử dụng để lưu lỗi sang cơ sở dữ liệu b ằn g phương thức execO của PDO cùng với ngày th á n g v à thời gian ch ín h xác, Sau đó việc gởi đến ob_end_clean{) sẽ xóa sạch bộ đệm dầu ra, gởi m ột tra n g lỗi tù y ý đ ến trìn h

du y ệt v à k ế t th ú c việc thực th i script

K ết quả của nhữ ng h à n h động này là th ậ m chí nếu d ã có m ột tra n g Web đan g được tạ o n h a n h k h i lỗi xảy ra, nó sẽ k h ô n g bao giờ th ấ y á n h sá n g ban

n gày vì nó sẽ bị loại bỏ v à được th a y th ế b ằng tra n g lỗi tù y ý M ặ t k h ác nếu

sc rip t thự c th i không có b ấ t kỳ lỗi nào, việc gọi sau cùng đến ob_end_flush()

sẽ giải quyết việc gởi tra n g đầy đủ v à sau cùng đến tr ìn h duyệt

Trang 15

T rong k h i b ạ n xem nó, cũng h ãy n h ìn vào b áng SQ Lite B ạn có th ể th ấ y

các th ô n g báo được đưa r a bởi sc rip t như được m inh họa ở đây:

1l13-Feb-2008 06:25;30IUndefíned variable: m yVar!/ch10/project01/

app.phpl28

2l13-Feb-2008 06:25:301include(missingfíle.php): íaiied to open

stream; No suctí file or đirectoryl /ch10/projecf01/app.phpl31

3l13-Feb-2008 06:25:30iinclude(): Failed opening 'm issingíile.php' for

inclusion (include_path=' ')l/ch10/project01/app.phpl31

M ột th iế t lặ p n h ư vậy làưi cho m ột Iihà quản trị n h à p h á t triể n dỗ duy trì m ột record th ư ờ n g trực của các lỗi script và quay trở về record n ày b ấ t

cứ lúc nào để xem hoặc kiểm t r a các lỗi trong k h i cũng bảo đảm rằ n g sự trả i

n g h iệ m người dùng là n h ấ t q uán và không phức tạp

Trang 16

1 7 0 C h ư ó n g 10: x ử lý các lỗi

Hỏi chuyên gia

Hỏi: Điều gi xảy ra nếu bản thân hàm xử lý lỗi tùy ý chứa một lỗi?

Đ áp: Nếu bản th â n p h ư ơ n g thúc xử lý lỗi tùy ý chứa một lỗi, lỗi s ẽ được chuyển hướng lên cơ cấu xử iý lỗi mặc định của PHP Do đó ví dụ nếu

m ã b ê n t r o n g m ộ t p h ư ơ n g t h ứ c lỏi t ù y ý tạ o r a m ộ t c ả n h b á o , c ả n h b á o

này sẽ được báo cáo theo cãp báo cáo lỗi hiện hành của PHP và được

x ỉ í lý b ở i p h u ơ n g th ứ c x ử lý lỗi m ặ c đ ịn h c ủ a P H P

Sử dụng các ngoại iệ

N goài các ỉõi, P H P 5 cũng giới th iệu m ột mò h ìn h ngoại lộ mới [ương tự

n hư mô h ìn h được sử dụng bởi những ngôn ngữ lậo tr ìn h k h á c n h ư J a v a và

P ython, T ro n g phương p h áp dựa vào ngoại lệ này, m ã chương tr ìn h được hao tvong rAỘt lchối và cốc ngoí^i lệ >1ươc tạo ''a bỏ'i '10 được "đón bổt"

và được giổi quyết ‘udi n iộ t hoặc n h iềa khô'i catch Bởi vì n h iều khô'i cAtch cõ

th ể thự c h iệ n được, các Iihà p h á t triề n có th ế bẩy (tra p ) các loại ngoại lô

k h ác n h au và xử lý mỗi loại ngoại lệ m ột cách khác nhau

Để m in h h ọ a điều này, hãy xem xét listin g sau đây, lis tin g n ày ccT tạo

m ộ t p h ầ n tử m ả n g không tồ n tạ i sử đụng m ột A rra y lte ra to r:

<’ php

/ / detine array

$cities » ãrray(

"United Kingdom ” => “ London",

"United States" => “ W ashington” ,

Trang 17

m ã b ên tro n g khô'i try (như xu ất h iệ n tro n g listin g trước), P H P dừng thực

th i khối tạ i điểm đó và b ắ t đầu kiểm tr a mỗi khôi catch đ ể xem có m ột phương thức xử lý tro n g ngoại lệ hay không Nếu m ột phương thứ c xử lý được tìm th ấ y , m ã bên tro n g khối catch th ích hợp được thự c th i v à sau đó các đòng sau khối try được thực thi Nếu không, m ột lồi n g h iê m trọ n g sẽ được tạ o r a và việc thực th i scrip t dừng tạ i điểm lỗi

Mọi đối tượng Exception đều chứa th êm một sô’ th ô n g tin m à có th ể được

sử dụng cho việc gỡ rối nguồn của ỉỗi Thông tin này có th ể được tru y cập thông qua các phương thức cài sẵn của đối tượng E xception v à chứa m ột thông báo lỗi mô tả, m ột m ã lỗi, tê n file và số dòng gây r a lỗi và m ột

b ac k trace của các lầ n gọi ra h àm d ẫn đến lỗi B ảng 10.3 liệ t k ê nhữ ng phương thức này

Và b ản ch ĩn h sửa sau đây của listin g trước m inh họa n h ữ n g phương thức

n ày đ an g sử dụng:

<?php

/ / detine array

$cỉties = array{

“ United Kingdom" => “ London",

"United States" => “ Washington",

Trang 18

172 Chướng 10: x ử lý các lỗi

} catch (Exception $e) {

echo “ ERROR: Something w ení w rong!\n” ; echo "E rror message: “ $e->getMessage() '‘\n ” ; echo “ Error code: “ $e->getCode() "\n ” ;

echo “ File name: “ $e->getFile() , "\n";

echo “ Line: “ $e->getLine() "\n ” ; echo 'Backtrace: " $e->getTraceAsString() 1

tạo ra ngoại lệ

dẫn đến lổi dưới dạng một m ảng

dẫn đến lỗi dưới dạng một chuỗi

• • • • • • •

Thủ th u ật

c ỏ t h ể x ứ lý c á c loại ngoại lệ k h á c nhau m ộ t cá c h k h á c n h a u b ằ n g v iệ c tạo

nhiều khốỉ catrh và gán các hành độníỊ khác nhau vào mỗi khối này Bạn sẽ thấy một ví dụ về điều nàỵ thêm nữa trong chương

Bây giờ nếu b ạn nghĩ về nó, có th ể b ạn m uôn k ế t luận rà n g các ngoại lệ chỉ là rượu cũ tro n g m ột b ìn h mới R ốt cuộc nhữ ng k h ả n ă n g đă được mô tả dường n hư h oàn to àn dễ d àng sao chép sử dụng m ột phương thức xử lý lỗi tùy ý n hư được mô tả tro n g p h ầ n trước Dù vậy, thực t ế phương p háp dựa vào ngoại lệ n ày tin h vi hơn nhiều so với vẻ bề ngoài bởi vì nó m ang lại

th êm nhữ ng lợi ích sau đây:

# Trong mô hình trỉiyền thống, cần kiểm tra giá trị trả vẻ của mọi hám

được gọi đ ể n hận dạng xem một lỗi đã xả y ra bav kbông và có hành động Sĩỉa chũa Điều n à v có th ể tạo ra m ã phức tạp không cẩỉì thiết và các khối mã điíợc xếp lồng sản Trong mô hình dựa vào ngoại lệ, một

Trang 19

khối catch có thể điíợc sử dụng đ ể đầy bất kì> lỗi x ả v ra trong khối mã

irìíớc D iều n à v loại bỏ n h u cầti về n h iều cuộc test lỗi p h â n tần g và nó

tạo ra m ã đơn giản bơn lủ dẻ đọc hơn.

» v ề bản chất mô hình tniyền thống có tinh m ệnh lệnh: nó đòi hỏi nhà

p h á t triể n su y n g h i q u a tổi cả lỗi m à có t h ể x ả v ra và viết m à đểXÌC lý

từ n g k h ả n ă n g n à y Trái lại, phương p h á p d ự a i>ào m ô h ìn h lin h hoạt

b ơ n M ộ t p h ỉ i ơ n g t h ứ c x ừ l ý n g o ạ i l ệ g e n e r i c l à m v i ệ c n h ĩC m ộ t l ư ớ i a n loàn, đ ó n bắt và x i'( ỉỷ thâm ch í các lỗi m à m ã X íỉ lý lỗi cụ th ể đ ã không đĩCỢC niết Đ iều n à y c h ỉ g iú p là m cho m ã ĩỉng d ụ n g m ạ n h hơn và kiên ciíờng irìcởc n h ũ n g tình hiiống không lítòng tn tớ c đĩCỢC.

K Bởi vì mô hình ngoại lệ đã sứ dụng mộ/ phương p h á p dựa vào đối tượng, các nhà phát triển đã có thểsữdiỊng nhũng khái niệm OOP về sự tbừa k ế (inheritance) và khả nãng mở rộng (extensibiỉity) đ ể tạo sub- class (class con) cho đối tỉiỢng Exception cơ sở và tạo nhĩìng đối tiíợng Exception khác nhau cho những loại ngoại lẽ khác nhan Diềỉi nàv làm cho có thể p h â n biệt giũa các loại lỗi khác nhau và x ứ lý mọi loại lỗi mộl cách kbác nhau.

^ Phtíơng pháp dựa vào ngoại lệ bỉiộc các nhà phái triển đìCa ra những quyết định khó khăn í,’ể cách x ứ lý các loại lỗi khác nhau Không giống

n h ư trong m ô h ìn h tru yền thống nơi các n hà p h á t tn ể n có th ể d ễ d à n g

bỏ qita (i>ô ỷ hoặc cố ý) các cuộc lest đ ể kiểm tra giá trị trà về của các

h à m , c á c ngoại lộ kh ô n g d ễ bỏ qu a n h ií vậv B ằ n g việc đ ò i hỏi c á c nh à

p h á t triể n tạo I'à tập hợp lạ i các khối catch, m ô b ìn h ngoại lệ buộc họ

su y n g h ĩ ĩ>è n h ữ n g ngnvôn n h â n và hậít quả cửa c á c lỗi nà cuối củng

d ã n đ ế n sự th iế t k ế tốt hơn và Sỉ[ thực thi m ạ n h bơn.

K huyết diểm duy n h ất? Các ngoại lệ dã được giới th iệ u chỉ tro n g PH P 5,

và k ế t quả chúng chỉ được tạo riên g bởi extension ngôn ngữ mới hơn chẳng

h ạ n n h ư SimpIeXML, P H P D a ta Object (PDO), Service D ata Objects (SDO),

v à S ta n d a rd P H P L ib rary (SPL) Đô'i với tâ't cả hàm P H P khác, cần phải kiểm t r a giá tr ị tr ả về của hàm dể tìm các lỗi và chuyển đổi nó th à n h m ột ngoại lệ (exception) b ằng th ủ công

Tạo hoặc đưa r a các ngoại lệ b ằng th ủ công theo cách n ày là m ột tác vụ cho câu lệ n h th ro w của PH P Câu lện h này cần được chuyển m ột th ô n g báo lỗi mô tả và m ột m ã lỗi tùy ý Sau đó nó tạo ra m ột đối tượng Exception sử dụng n h ữ n g th a m sô n ày v à làm cho th ô n g báo và m ă có sẵ n cho phương thức xử lý ngoại lệ T iến tr ìn h này dược m inh họa tro n g listin g sau đây:

C h ư ớ n g 10: x ù lý các lỗi _ 1 7 3

Trang 20

1 7 4 C h ư ở n g 1 0 : x ử lý c á c lỗi

<’í’ php

// set file name

/ / attem pt to copy and then đelete file

$file = 'đum m y.txt';

try {

if {!file exists($fiỉe)) ỉ

t h r c w r e w E x c e p tỉo n (“ r ỉle '$ file ’ w a s not íGund,");

I 'f (fi:e_extst3í"$f:le.new "}) ! throw new Exception(“ Destination file '$file.new’ already exists.” )'

1

if (!copv($file, "$íile.n9w ” }) { throw new Exception(“ filfi '$file’ couid not be copieđ."),

)

íf (!unlínk($file)) { throw new Exception(“ File ’$file’ Cũuld not be rem oved,” };

)

í catch {Exception $e) {

echo ‘Oops! Something bad happened on ỉ i n e ' , $e->getLíne() ,

ở đây p h ụ thuộc vào k ế t quả của các h o ạ t động file k h á c n h au , m ộ t ngoại

lệ mới được đưa r a bởi scrip t b ằng th ủ công Sau đó ngoại lệ n ày được đón

b ắ t bởi phương thức xử lý ngoại lệ generic v à thông tin d à n h riê n g cho lỗi được tríc h x u ất và được h iể n th ị cho người dùng

Trang 21

C h ư d n g 10; x ù lý các íỗi _1 7 5

nhau vì nó cho p hép b ạ n sử dụng một khối catch riên g b iệ t (và m ã xử lý riên g biệt) cho mỗi loại ngoại lệ Sau đây là m ộ t b ản chỉnh sửa của ví dụ trước m inh h ọ a phương p háp này:

<?php

/ / subclass Exception

class MỉssingPileException extends Exception I Ị

class DuplicateRleException extends Exception { )

ciass PilelOException extends Exception {1

/ / set file name

// attem pt to Cũpy and then delete file

$file = 'dum m y.txt’ ;

trỵ {

if (!file_exists($file)) { throvv new MissingFileException($file);

1

if (file_exlsts("$file,new ")) í throvv new DuplicateFileException('‘$file,new’’);

}

if (!copy($fiie, “ $file.new” )) { throw new FilelQException(“ $fỉle.new” );

I

if (!unlin k($ file )) { throw new FilelOException($fiie);

1

} catch (MissingPileException $e) {

echo 'ERROR: Could not find file \ ” , $e->getMessage() , exit();

} catch (DuplicatePileException $e) (

echo 'ERROR: Destinaíion file V’ $e->getMessage() 'V already exỉsts’; exit();

I catch (PỉlelOException $e) {

echo 'ERROR: Could not pertorm tile inpuưoutput operation on file \ " .

Trang 22

1 7 6 _ C h ư ớ n g 1 0 : x ử lý c á c lỗi

$e->getMessage() exit{);

} catch (Exception $e) I

echo ‘Oops! Something bad happened on line ‘ , $e->getLine() ‘

ba Exception Iià.v, lỉliối catch sau cùng là m ột phương th ú e xử lý "bao tĩùm "

generic: Các Iigoại lệ khỏiig được xử lý bởi các khô'i cụ th ế nơn ở tr é n nó sẽ

th ấ t bại và sẽ được giải quyết bằn g phương thức xử lý

nàv-Hỏi chuyên gia

H ỏ i: T ô i đ ă th ấ y rằ n g c á c n g o ạ i lệ k h ô n g đ ư ợ c đ ó n b ắ t tạ o ra m ộ i lỗi

p g h iê m trọ n g kh iế n c h o s c n p t k ế t th ú c đ ộ t ngột T ô i cc th ể th a y d ổ i (iiể u

n à y đ ư ợ c h a y kh ò ng ?

thay thế phương thức xử lý ngoại lệ mặc định của PHP bằng mâ tùy ý riêng của bạn giống y như cách với set_error_handler() Tuy nhiên, có một điều kiện quan trọng cần lưu ý ở dây Như bạn đã thấy phương thức

xử lý ngcại lệ mặc định của PHP hiển thị một thông báo và sa u đó kết thúc ngoại !ệ script s ử đụng một phương Ihúc xử lý ngoại lệ tùy ý cho

p h é p giới n ạn Kiểm so á t h à n n vi này; Trong khi b ạ n c ó thể th ay th ế kiểu

cách và diện mạo của sự hiển thị thông báo, bạn không thể làm cho

s c rip t tiế p tụ c th ự c th i bên n g o à i đ iể m n ơ i n g o ạ i lệ đ ả đ ư ợ c tạ o

Bài học của v ấ n đề n ày là m ột ngoại lệ không được đón b ắ t sẽ luôn dẫn đến việc k ế t thúc script Đây ià lý do tạ i sao luôn n ê n bao h àm m ột khối catch generic tro n g m ă xử lý ngoại lệ để đón b ắ t t ấ t cả ngoại lệ được đưa ra bởi script, b ấ t k ể loại

Trang 23

C h ư d n g 10; x ử íý các lỗi 1 7 7

Thực hành 10.2: H iệu lực hóa đầu vào của Form

Bây giờ k h i b ạn đã hiểu cơ bản cách làm việc của các ngoại lệ cũng như cách đưa r a v à đón b ắ t các ngoại lệ tùy ý, hãy áp dụng k iế n thức này vào

m ột dự á n nh ỏ m in h h ọ a thực t ế những công cụ này Ví dụ tiế p th eo này cho

Sau đây là m ã (art.php):

<!DOCTYPE htm l PUBLIC “ -//VV3C//DTD XHTML 1.0 Transitional//EN"

Trang 24

<option valLie=’V=ỉn Gngh” >van Gogtì</npíion>

<option va[ue="ChagaH">C‘ iagall</option>

Trang 25

if (em pty($artist)) { íhrow new lnputException('Artist’):

1

if (em pty($medium )) { throw new lnputException{'Medium');

Trang 26

1 8 0 C h ư d n g 1D: xử lý c á c lỗi

if ($max < $m in) { throvv new LogicalException('Maximum price cannot be less than

Med'um: Smeclium \r\n PrỉCti; Belweer $m in and $max \r\n

echo ‘<div class="error” >ERROR: Please provide a valid value for the

fỉeld marked \ ” $e >getMessage() , ‘V«ydiv>’;

8xit();

} catch (LogicalException $e) ( echo '<div class=” error">ERROR; $e->getM essage() ‘</div>’- exitO;

} catch (MailException $e) { echo '<div c!ass="error">ERROR: Unable to deliver email message</ div>’ ;

file_put_contentsCerror.log’, T , date{“ (l-M -Y h:i:s’’ , mktimeO) ,

‘] Mail delivery error to; ‘ $e->geíMessage{) ‘^n ” , FILE_APPEND);

exitO;

Trang 27

M ột k h i form được gởi, scrip t t ắ t chức năn g báo cáo lỗi cho t ấ t cả ngoại

tr ừ các lỗi n g h iêm trọ n g và định nghĩa b a loại ngoại lệ mới: InputE xception cho các lỗi tro n g đầu vào form, LogicalException cho các lỗi tro n g logic đầu vào v à M ailE xception cho các lỗi tro n g việc gởi m ail N hững ngoại lệ n ày là nhữ ng p h ầ n m ở rộng đơn giản của đô'i tượng E x ten sio n generic

T iếp theo, m ộ t khối try được sử dụng để đóng gói logic xử lý script Đầu tiê n , các trường n h ậ p liệu khác nhau dược te s t để k iểm tr a tín h n h ấ t quán; các lỗ i tr o n g dữ liệ u trư ờ n g tạ o r a m ộ t I n p u tE x c e p tio n h o ặ c m ộ t LogicalExeeption M ột k h i dữ liệu đ ã được hiệu lực hóa, nó được đ ịn h dạng

th à n h m ộ t th ô n g báo e-mail, được chuyển sử dụng h àm m a iio của PHP Nếu h à m m a iio t r ả về false, biểu th ị rằ n g việc chuyển th ô n g báo không

th à n h công, m ột M ailException được đưa ra Nếu không, m ột th ô n g báo

th à n h công (success) được in ra

Các ngoại lệ k h ác n hau được tạo ra bởi logic xử lý không chỉ được bỏ qua

T hay vào đó bô'n khối catch (mỗi khôi cho ba loại ngoại lệ được đ ịn h nghĩa

và raộ t khôi generic) sẽ đẩy những ngoại lệ này, in th ô n g báo người dùng

th íc h hợp của lỗi v à tạm dùng việc xử lý script Từng ngoại lệ được xử lý hơi khác n hau dể m in h họa mỗi thường trìn h xử lý ngoại lệ có th ể được tùy biến

n hư t h ế nào Ví dụ, M ailException được ghi n h ậ t ký san g m ột file với ngày

th á n g v à th ờ i gian và địa chỉ e-m ail người n h ậ n v à InputE xceptions và LogicalExceptions tạ o r a các th ô n g báo lỗi khác nhau

Trang 28

1 8 2 C h ư ớ n g 10: X ử lý c á c lồi

H ìn h 10.6 m inh họa k ế t quả khi m ột InputE xception được tạo ra

Và h ìn h 10.7 m inh họa k ế t quả k h i việc chuyển m ail th ấ t bại và một

M ailException được tạ o ra

i)Pt<iịe<t iO-ĩĩ VaụdẠịimi^rm InpiA ■ M02ỉH« Firefõ»

P roject 10-2: V alidatlng Form liiput

Trang 29

Ngoài việc bẫy v à xử lý các lãi vào thờ i gian chạy, cùng thường n ên duy

t r ì m ột record b á n thường trực về các lỗi đã được tạo r a bởi m ột ứng dụng

vì các mục đích gỡ rối hoặc kiểm tra Đó là nơi h à m error_log() của P H P có hiệu lực: nó cho phép bạn gởi các thông báo lỗi sa n g m ột íĩle đĩa hoặc địa chỉ e-m ail k h i chúng xảy ra

H àm error_log() cần tối thiểu hai đối số: thông báo lỗi cần được ghi n h ậ t

ký và m ột giá tr ị số nguyên biểu th ị đích log (n h ậ t ký) G iá tr ị số nguyên

n à y có th ể là 0 (file log hệ thống), 1 (một địa chỉ em ail), hoặc 3 (m ột file đĩa) M ột đ ịa chỉ e-m ail hoặc đường đẫn file đĩa n ê n được xác đ ịn h là m ột đối sô' th ứ b a cho e rro rjo g () k h i cần thiết

Sau đây là m ột ví dụ m inh họa điều này làm việc như th ế nào:

<?php

/ / attem pt datatiase connection

$m ysqli = new m ysqli(“ localhosV’, 'user’’, ‘ pass", "m usic");

Trang 30

1 8 4 C h ư ơ n g 1 0 : X ử lý c á c lỏi

/ / attem pt query execution

/ / iterate over result set

/ / p rin t each record and its fields

//o ư tp u t: “ 1:Aerosmìth \n 2:A bba\n

$sql = “ SELECT a rtỉs U d , a rtisL n a m e FROM a rtis ts ” ;

if (Sresult = $m ysqli->query($sql)) {

if ($result->nunLfO ws > 0) í while($row =: $re3Ult->fetch_array()) { echc $ row [‘3rtist_id’i $ raw ['aríisí_nam e’l .

}

$result'>close();

} else { 3cho “ No records matching your ũuery v/ere founà,";

G iả sử m ột user nam e hoặc passw ord không đúng, sc rip t n a y sé ghi n h ậ t

ký th ô n g báo sau đây tro n g fĩle debug.log:

ERROR: Could not connect Access đenied fo r user 'user' @ 'localhost' (using passvvord: YES)

K há dễ dàn g k ế t hợp tiệ n ích ghi n h ậ t ký lỗi n à y với m ột phương thức xử

lý lỗi tùy ý để bảo đảm rằ n g t ấ t cả lỗi scrip t được ghi n h ậ t ký s a n g m ột file Sau đó là m ột ví dụ m inh họa điều này:

<?php

/ / custom handler

íunction myHandler($type, $m sg, $file, $line, Scontext) {

Trang 31

error_logC‘ [" dateC‘d 'M -Y h:i:s” , mktimeO) “ ] $m sg on line

$line of $file\n” , 3, 'debug.log');

đ ể tr ả quyền điều k h iể n trở lạ i phương thức xử lý lỗi m ặc đ ịn h của PH P và

xử lý lỗi m ột cách b ìn h thường

Gỡ rối các lỗi

Vứi n h ữ n g ứng đụng phức tạ p hơn, cần ph ải đóng gói các tá c vụ thường được sử dụng th à n h n h ữ n g th à n h p hần độc lập (các h à m v à class) v à im port nhữ ng th à n h p h ầ n này k h i cần th iế t vào các sc rip t P H P T rong k h i phương pháp n à y chắc ch ắn cải th iệ n việc duy trì m ã, nó có th ể chứng tỏ là một

g án h n ặ n g k h i mọi th ứ không làm việc như m ong đợi Ví dụ, m ột lỗi tro n g

m ột th à n h p h ầ n h oàn to à n có th ể ản h hưởng đến đúng hàm của những

th à n h p h ầ n k h á c v à việc tru y v ế t iỗi này trở lại qua call stack (ngăn xếp gọi) thư ờng là m ộ t trả i nghiệm dài (và gây th ấ t vọng)

Để g iảm sự cực nhọc tro n g tiế n trìn h này, có nhừ ng công cụ k h ác nhau

m à b ạn có th ể sử dụng Công cụ đầu tiê n được cung cấp bởi chính P H P dưới

d ạn g h à m debug_print_backtrace() H àm này in m ột d an h sách t ấ t cả lệnh gọi h à m d ẫ n đ ến m ột lỗi cụ th ể dể giúp bạn n h ậ n d ạn g n h a n h nguồn Để

m inh h ọ a trự c tiế p điều n ày , xem xét script sau đây, sc rip t n ày chứa m ột lỗi cô' ý:

C h ư d n g 1 0 : x ù lý c á c lỗi 1 8 5

Trang 32

1 8 6 _ C h ư d n g 1 0 : x ử lý c á c lỗi

<?php

// custom error handler

/ / prints a stack trace if an error occurs

putHc tunction _constriJct($nL!m1, $num2) {

$ex = new Exampie($num1, $num2);

1)

$page = new Page{10,1);

echo 'Code execưtion successM ’ ;

?>

ở đây, sc rip t sẽ tạ o ra m ột cảnh báo 'division by zero”, k h ô n g p h ải do

m ột lỗi tro n g đ ịn h n g h ĩa class Page m à là đo m ột cản h báo được tạo r a bdi

phương thức runO ở p h ía dưới x a hơn tro n g call stack H ìn h 10.8 m inh họa

th ô n g báo lỗi m à người ta thường th ấ y tro n g trường hợp này

Gỡ rôi m ột lỗi n h ư vậy thực r a có th ể trở n ên k h á bề bộn đặc b iệ t k h i các

đ ịn h n g h ĩa h à m v à class được giữ trong các file riên g biệt Tuy nhiên, bởi vì

Trang 33

C h ư ơ n g 10: x ử lý c á c lỗi 1 8 7

phương thức xử lý lỗi tro n g scrip t này tự động in m ột b ack trace k h i m ột lỗi xảy ra, k h ô n g quá khó n h ậ n dạng h àm đang gây r a lỗi H ìn h 10.9 m in h họa đầu ra được ch ỉn h sửa, th ể hiện backtrace

iW B iỉriiĩ II11

< ậ l - ^ J u hKp,f;lâ<iiwựp^ip 6 «b<»ĩkựchiO>H^in»</p.rt-to^Vdce~l ph Ị ~ T r ^

\V aỉT iin g CHvi$ion b>y zerc tu C : ^ o g r a i t i F ile $ U n (e m « t

T D d s\A p a c h e ^ td o (ỉ\p h p 6 * b o o k V c h ỉ0 1 ìỉtiiig ỉ\p iin t* b a c V Q * a e e 'l.p h p OD ỉìnc 3 3

Đ ế b iế t th ê m th ô n g tín và c á c hướng dẫn cài đặt, d i đ ến w w w x d e b u g c o m /.

M ột phương p háp th ậ m chí phức tạp hơn đòi hỏi sử dụng class PH P Debug, class n ày có s ẩ n m iễn phí từ www.php-debug.com/ C lass n ày cung cấp m ột fram ew ork hữu dụng để tru y vết việc thực th i sc rip t; th e o dõi và

k ế t xu ất các b iến , tín h th ờ i gian thực th i và thực h iệ n n h ữ n g tá c vụ gỡ rối

Mi Cxsưní)le->_ c o ỉ i s t r u c t (1 0 , l) c a l l c d a t ỈC :S P cg y iQ tt r i Ằ e » \ l i i c e t n e c

T ô ô i a \ * p B C h « S h t d o c s \ p h p é - b ô o J c \ c h l O S l i s ĩ i n g s \ p r i r , t - b a c í ? t r « e e - l p h p : 113

9 3 f ' a 3 C - > _ í - o n s c c u ữ t < 5 0 1) e o l l e d X n t « f n e c

T o o j , a \ A p f t c h c \ h t d & ữ 3 \ S h i o s U d c t / i Q s S p t i n t - b o c K c r a c c - 1 p h p s i 8 j

Hình 10.9 M ột lỗi PHP được cảl tiến bằng m ột backtrace

Để sử đụng class này, dovvnload nó và đặt các fĩle class tro n g th ư mục ứng dụng Sau đó ch ỉn h sửa listin g trước sử dụng nó n h ư sau:

Trang 34

1 8 8 C h ư ớ n g 1 0 : X ử lý c á c lỗi

<?php

/ / custom error hanđler

// prints a stack trace if an error occurs

íunction myHandíer($type, $msg, $file, Sline, $coníext) {

$debug->dump(func_get_args(), ‘method args’);

$ex = new Example($num1, $num2);

Trang 35

’renđer_type’ => 'HTML’ , 'render_m ode' => Table’, 'replace_errorhandler’ => false,

Trang 36

1 9 0 C h ư ơ n g 10: x ử lý các lỗi

$page = new Page(10,1);

echo 'Code execuíion successíul';

?>

PHP_D ebug cung cấp cho m ột đối tượng với các tiệ n ích k h ác n h a u để giúp các n h à p h á t triể n gỡ rối m ột script Ví dụ, phương thức a d d o của đối tượng có th ể được sử dụng để tru y vết việc thực th i sc rip t b ằ n g việc cạo các

th ô n g báo tạ i các điểm do người dùng định nghĩa tro n g sc rip t ohẳrig h ạ n như k h i n h ập m ột hàm hoặc m ột vòng lặp

Tương tự, phương thức đumpO có th ể dược sử dụng để ghi n h ậ t ký g iá trị cũa m ột biến vào m ột khoảng thờ i gian nào đó tro n g k h i phương thức displayO có th ể được sử dụng dể gởi t ấ t cả đầu r a gỡ rối s a n g th iế t bị đ ầu ra Trong lisitn g trước, phương thức displayO này được sử dụng bởi phương thưc xủ ly lõi tùy y nếu m ột lỗi xáv ra đẻ tư động tạo ra m ột b ack trace đượr

đ in h dạng gọn g àng cùa tấc cả lệiih gọi dẫn đến lỏi

H ìn h 10.10 m inh họa đầu ra của listin g trước

N hư được m in h họa tro n g h ìn h 10.10, PHP_Debug có th ể cung cấp một record phức tạ p hơn nhiều về các iệnh gọi h àm đẫn đến m ộ t lỗi so với h à m debug_print_backtrace() b ìn h thường của PHP

yọ* racg-2 PhD _.cor«íuct^ Dcđrrplt vđTiable

Trang 37

C h ư ờ n g 1 0 ; x ử lý các lỗi _ 1 9 1

Tóm tắ t

K ết th ú c chương này bạn hiểu rõ hơn nhiều về cách làm việc của ữaixie- work xử lý lỗi của P H P và cách bạn có th ể tùy b iế n nó để đáp ứng những yêu cầu của ứng dụng cụ thể Chương này thảo lu ận h a i mô h ình: mõ hình dựa vào lỗi trước đó và mô h ìn h ngoại lệ mới hơn được giới th iệu tro n g P H P

5 T ín h đễ sử dụng và k h ả n ản g mở rộng giúp m ô h ìn h ngoại lệ P H P 5 lợi

th ế hơn các kỹ th u ậ t kém nguyên thủy hơn, sớm hơn Tuy n h iên , bởi vì nó

cũng k h ô n g được hỗ trợ tô"t tro n g các th ư viện cốt lõi, hầu h ế t các yêu cầu

p h á t tr iể n ứng dụng là m ột sự k ết hợp đúng đ ắ n h a i phưcmg pháp

N goài việc hướng d ẫn b ạn t ấ t cả về các lỗi và ngoại lệ, chương này cũng giới th iệ u về m ộ t sô' h àm tiệ n ích của PH P đ àn h cho việc ghi n h ậ t ký v à gỡ rối v à nó đà m in h họa m ột công cụ bên th ứ ba, gói PHP_Debug, để đ ạ t được

th ô n g tin b ack trace chi tiế t k h i các lỗi xảy ra Sau cùng, h a i dự á n - m ột bộ ghi n h ậ t ký lỗi cơ sở dữ liệu v à một bộ hiệu lực h ó a đầu vào form - đ ã m inh chứng lý th u y ế t n ày có th ể được áp dụng trong thực t ế n h ư th ế nào

Đ ể tìm hiểu th ê m về những chủ đề được đề cập tro n g chương này, hãy xem x é t đi đến các lin k sau đây:

Các ngoại ỉệ (exception), Ịại u'ii'U'.Ị}hp.ncưexceplions

K C ác h à m X 1 Ỉ lý lỗi tạ i uniw php.nei/crror/nnc

H Web site PHP_Debỉ(g chinh thức tại imnyphp-debiig.com

Trắc nghiệm

1 H ãy nêu h a i lợi ích của việc sử đụng mô h ìn h dựa vào ngoại lệ

2 Các loại lỗi sc rip t nào không th ể được đón b ắ t b ằn g m ột phương thức xử lý lỗi tùy ý?

3 M ột bộ đệm đầu r a (output buíĩer) lâ gì? Nó hừu dụng n h ư th ế nào?

C ung cấp m ộ t ví đụ thực tiễ n m inh chứng cho tín h hữu dụng của nó

4 P hương thứ c xử lý lỗi nào sẽ được kích h o ạt sau k h i dòng cuối cùng của từ n g k h ố i m ã sau đây được thực thi;

Trang 38

cản h báo P H P có tb.ể được chuyển đổi th à n h các ngoại lệ n hư th ế nào.

6 V iết m ột chương trìn h á ể tự động gởi e-m ail mọi n g o ại lệ không đón

b á t được tro n g m ột scrip t đến m ột n h à quản trị

Trang 39

C h ư d n g 11: B ảo vệ an toàn P H P _ 1 9 3

Nbững k ỳ năng v à k h á i niệm chính

ầẵ Ngăn các loại tấn công thông thường bằng cách làm vệ sinh đầu vào

I’à đẩu ra

K Tăng sự an ninh của các file ứng dụng, cơ sở d ữ liệu, và session

ÊÊ Học hiện Ịực hỏa các chỉiỗi, số, và ngày tháng

# Bắt đầu sứ dụng các bíềìi thức thông thường đ ể hiệu lực hóa đầu

vào

• Học về x á c lập a n ninh của PHP

và sử dụng dữ liệu từ những nguồn bên ngoài tro n g các ứng dụng

PH P B ạn đ ã xử lý th à n h công dữ liệu được gởi từ các form trực tuyến, k ế t nôl các tra n g Web với một cơ sở dữ liệu để tạo tra n g động v à tru y tìm th ô n g tin được m ã h ó a bằn g XML

Bây giờ, tro n g k h i tíc h hợp với tấ t cả nguồn dữ liệu b ên ngoài n ày có th ể

làm cho các ứng dụng P H P trở n ên thích d áng hơn và hữu dụng hơn, vẫn

còn m ột số rủ i ro cần lưu ý Các ứng đụng PH P không an to à n dễ bị tấ n

Trang 40

công bời những người dùng có ý đồ xấu tro n g k h i đầu vào ứng d ụ n g được hiệu lực h ó a không đúng cách có th ể k h iến cho các p hép tín h v à báo cáo trở

n ê n sai N hững điểm yếu n ày không chỉ có th ể k h iế n cho là m hư h ò n g và

m ấ t m á t dữ liệu đ áng k ể m à chúng còn có th ể gây bôl rôl tộ t cùng cho các

n h à p h á t tr iể n ứng dụng tự hào

Đó ỉà nơi chương này p h á t huy tác dụng, T rong các tr a n g tiế p theo chưcmg n ày g.iới th iệu bạn những kỹ th u ậ t k h ác n h ai.1 m à b ạn có th ể áp dụng để hiệu !ực k ó a đẩu vàc của ứng dụng, do đó làm clio nó a n to à n hơn

v à m ạn h hơn Ngoài ra, chương sẽ đưa r a những ví dụ thực tiễ n về việc làm A'ệ sin h đầu vào v à đầu ra, th ả o luận m ột sc biến quan trọ n g liê n quan đến

an n in h tro n g kỹ th u ậ t PH P và hiíớng bạn sa n g nhữ ng nguồn tà i nguyên

trực tuyến k h ác nh au nơi b ạn có th ể tìm hiểu th ê m về an n in h ứng dụng

PH P

Làm vệ sính đẩu vào và đầu ra

Lã m ột n h à p h á t triể n ứng dụng Web, có m ột việc không để gì m à bạn sẽ

p h ải học chịu đựng: luôn có những người ở đó cười khúc k h ích k h i tìm th ấy được nhừ ng lỗ hổng tro n g m ã của bạn và k h ai th á c nhữ ng lỗ hổng này vì

nhữ ng ý đồ xấu.

P h ầ n lớn thờ i gian, nhữ ng k h ai th á c này bao gồm gởi đến ứng dụng của

b ạn đầu vào được "giả m ạo khôn ngoan” n h ằm "đánh lừa" nó làm m ột điều nào đó m à thực r a nó không làm M ột ví dụ th ô n g thư ờng về loại cuộc k h ai

th á c n ày là "cuộc tấ n công tiê m SQL", tro n g đó m ộ t kẻ tấ n công từ xa điều

k h iể n cơ sở dữ liệu b ằng m ột query SQL nhúng b ên tro n g đầu vào của form

Do đó, m ột tro n g nhữ ng điều quan trọ n g n h ấ t m à m ột n h à p h á t tr iể n p h ải làm trước k h i sử dụng b ấ t kỳ đầu vâo được cung căp bởi người dùng la "làm

đặc b iệ t r a khỏi nó

M ột cách tương tự, nếu ứng dụng sẽ sử dụng dữ liệu được tru y tìm từ nhữ ng người từ xa, cần luôn 'là m sạch" dữ liệu n ày trước k h i h iể n th ị nó cho người dùng Việc không ỉàra điều này có th ể cho p hép các k ẻ tấ n công

n h ú n g nội dung độc hại vào các tra n g Web của b ạ n m à b ạ n k h ô n g th ể biết

M ột ví dụ phổ biên về loại k h a ỉ th á c n ày là "cuộc tấ n công v iế t scrip t giữa các site" tro n g đó m ột kẻ tấ n công có k h ả n ă n g tru y cập dữ liệu người đùng

n h ạy cảm b ằn g cách lắp ngược (piggyback) m ă J a v a S c rip t hoặc m ã form HTML độc h ạ i vào các tra n g Web của bạn G hi n h ớ điều này, điều cần th iế t

là h ãy luôn chuyển đầu r a qua m ột thường trìn h là m vệ sin h trước k h i làm cho nó có s ẵ n cho người dùng

C h ư ơ n g 11: Bảo vệ an to à n PHP

Ngày đăng: 03/12/2015, 20:39

HÌNH ẢNH LIÊN QUAN

Hình  10.4  Một  trang  lỗi  sạch - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh 10.4 Một trang lỗi sạch (Trang 15)
Hình  in .5   Một  Web  lorm  cho  người  dùng  (ĩặ!  jpột  đơn  đặt  hàng  sho  sản  phẩm  Tiỹ - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh in .5 Một Web lorm cho người dùng (ĩặ! jpột đơn đặt hàng sho sản phẩm Tiỹ (Trang 28)
Hình  10.6  Kết  quả  của  việc  đón  bắi  mội  (npuỉException  khi  xử  lý  Wei)  torm - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh 10.6 Kết quả của việc đón bắi mội (npuỉException khi xử lý Wei) torm (Trang 28)
Hình  10.7  Kết  quả  của  việc  đón  bắt  m ội  MailException  khỉ  xử  lý  Web  form - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh 10.7 Kết quả của việc đón bắt m ội MailException khỉ xử lý Web form (Trang 29)
Hình  10.10  Một  backtrace  được  tạo  ra  bời  góí  PHP.Debug - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh 10.10 Một backtrace được tạo ra bời góí PHP.Debug (Trang 36)
Hình  12.2  MỘI  Web  form  dế  nhập  thãng  lin   m ail  server - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh 12.2 MỘI Web form dế nhập thãng lin m ail server (Trang 78)
Hình  12.5  Đầu  ra  của  lệnh  phpinfo(),  hiển  thị  extensian  PECL  mứi - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh 12.5 Đầu ra của lệnh phpinfo(), hiển thị extensian PECL mứi (Trang 81)
Hình  A.5  Biên  dịch  PMP - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A.5 Biên dịch PMP (Trang 94)
Hình  A  9  Oái  đặt  MySUL  đang  (iến  triển - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A 9 Oái đặt MySUL đang (iến triển (Trang 98)
Hình  A '13  Xác  lặp  password  quản  trị  (adm inistrator) - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A '13 Xác lặp password quản trị (adm inistrator) (Trang 100)
Hình  A-16  Nhập  thQng  lin   server  Apache. - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A-16 Nhập thQng lin server Apache (Trang 101)
Hình  A-18  Chọn  vị  trí  cằi  dặt  Apaohe. - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A-18 Chọn vị trí cằi dặt Apaohe (Trang 102)
Hình  A-20  Cẵ'u  trúc  thư  mục  được  tạo  khi  mử  gói  một  bản  phân  phối  binary  PHP  trong - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A-20 Cẵ'u trúc thư mục được tạo khi mử gói một bản phân phối binary PHP trong (Trang 103)
Hình  A.21  Các  điểu  khiển  setver  Apache  trên  Windows. - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A.21 Các điểu khiển setver Apache trên Windows (Trang 105)
Hình  A*22  Xem  đẩu  ra  của  lệnh  phpintD  (). - Kỹ thuật và thủ thuật lập trình hướng đối tượng PHP   tập 2  phần 2   nguyễn minh, lương phúc
nh A*22 Xem đẩu ra của lệnh phpintD () (Trang 108)

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w