Tôi định cung cấp cho bạn một cuộc thảo luận bất thường nhất về kiểm soát lỗi.
Tôi đã xây dựng một trình xử lý lỗi rất tốt cho một ngôn ngữ cách đây nhiều năm và mặc dù một số tên đã thay đổi, nhưng nguyên tắc xử lý lỗi vẫn như ngày nay. Tôi đã có một hệ điều hành đa tác vụ được xây dựng tùy chỉnh và phải có khả năng khôi phục khỏi lỗi dữ liệu ở mọi cấp độ mà không bị rò rỉ bộ nhớ, tăng trưởng ngăn xếp hoặc sự cố. Vì vậy, những gì sau đây là hiểu biết của tôi về cách các lỗi và ngoại lệ phải hoạt động và chúng khác nhau như thế nào. Tôi sẽ chỉ nói rằng tôi không hiểu về cách thức hoạt động bên trong của try catch, vì vậy tôi đoán một số biện pháp.
Điều đầu tiên xảy ra trong quá trình xử lý lỗi là chuyển từ trạng thái chương trình này sang trạng thái chương trình khác. Điều đó được thực hiện như thế nào? Tôi sẽ làm điều đó.
Về mặt lịch sử, các lỗi cũ hơn và đơn giản hơn, và các ngoại lệ là mới hơn, phức tạp hơn một chút và có khả năng. Các lỗi vẫn có hiệu quả cho đến khi bạn cần giải quyết chúng, tương đương với việc giao một vấn đề khó cho cấp trên của bạn.
Lỗi có thể là số, như số lỗi và đôi khi với một hoặc nhiều chuỗi liên kết. Ví dụ: nếu xảy ra lỗi đọc tệp, bạn có thể báo cáo lỗi đó là gì và có thể bị lỗi. (Hay, đó là một bước tiến so với việc chỉ bị rơi như ngày xưa.)
Điều không thường được nói về các ngoại lệ là ngoại lệ là các đối tượng được xếp lớp trên một ngăn xếp ngoại lệ đặc biệt. Nó giống như một ngăn xếp trả về cho luồng chương trình, nhưng nó giữ trạng thái trả về chỉ dành cho các trys và bắt lỗi. (Tôi thường gọi chúng là ePush và ePop, và? Abort là một lần ném có điều kiện sẽ ePop và phục hồi đến mức đó, trong khi Abort là một lần chết hoặc thoát hoàn toàn.)
Ở dưới cùng của ngăn xếp là thông tin về người gọi ban đầu, đối tượng biết về trạng thái khi lần thử bên ngoài được bắt đầu, thường là khi chương trình của bạn được bắt đầu. Trên cùng, hoặc lớp tiếp theo trên ngăn xếp, với phần trên là con và phần dưới là cha, là đối tượng ngoại lệ của khối try / catch bên trong tiếp theo.
Nếu bạn đặt miếng thử bên trong, bạn đang xếp miếng thử bên trong lên trên miếng thử bên ngoài. Khi lỗi xảy ra trong lần thử bên trong và phần bắt bên trong không thể xử lý được hoặc lỗi được chuyển sang phần thử bên ngoài, thì quyền điều khiển được chuyển cho khối bắt bên ngoài (đối tượng) để xem nó có thể xử lý lỗi hay không, tức là Người giám sát của bạn.
Vì vậy, những gì ngăn xếp lỗi này thực sự làm là có thể đánh dấu và khôi phục luồng chương trình và trạng thái hệ thống, nói cách khác, nó cho phép một chương trình không làm sập ngăn xếp trả về và làm rối tung mọi thứ cho người khác (dữ liệu) khi có sự cố. Vì vậy, nó cũng lưu trạng thái của bất kỳ tài nguyên nào khác như các vùng cấp phát bộ nhớ và do đó nó có thể dọn dẹp chúng khi bắt xong. Nói chung, đây có thể là một điều rất phức tạp, và đó là lý do tại sao việc xử lý ngoại lệ thường chậm. Nói chung, khá nhiều trạng thái cần phải đi vào các khối ngoại lệ này.
Vì vậy, một loại khối try / catch thiết lập một trạng thái để có thể quay trở lại nếu tất cả những thứ khác bị rối. Nó giống như cha mẹ. Khi cuộc sống của chúng ta rối tung lên, chúng ta có thể ngã vào lòng cha mẹ và họ sẽ ổn định trở lại.
Hy vọng tôi đã không làm bạn thất vọng.
Errors are generally unrecoverable
<- thực ra, điều này không thực sự đúng.E_ERROR
vàE_PARSE
là hai lỗi không thể khôi phục phổ biến nhất (có một vài lỗi khác) nhưng phần lớn các lỗi bạn sẽ thấy trong nhà phát triển là có thể khôi phục được (E_NOTICE
,E_WARNING
et al). Thật không may, việc xử lý lỗi của PHP là một mớ hỗn độn - tất cả mọi thứ đều kích hoạt lỗi một cách không cần thiết (ví dụ như phần lớn các chức năng của hệ thống tệp). Trong trường hợp ngoại lệ chung là "cách OOP", nhưng tiếc là một số các API OOP mẹ đẻ của PHP sử dụng lỗi thay vì ngoại lệ :-(