Hãy nói về một cái gì đó hoàn toàn khác nhau. một phần mạnh mẽ của mã hướng đối tượng được gọi là ngoại lệ
Trong index.php
, chúng tôi tạo một đối tượng BrokenShip
. Tôi sẽ làm một cái gì đó điên rồ, các bạn. Tôi sẽ nói, $brokenShip->setStrength[]
và vượt qua nó. banana
dòng 1 - 4use Model\BrokenShip;. dòng 6 - 13$brokenShip = new BrokenShip['Tôi hỏng quá'];$brokenShip->setStrength['banana'];. dòng 16 - 146
Sức mạnh đó không có nghĩa lý gì. Và nếu chúng ta cố gắng chiến đấu bằng con tàu này, chúng ta sẽ gặp một số lỗi. Nhưng khi chúng ta làm mới. tốt, đó là một lỗi. nhưng không chính xác những gì tôi mong đợi
Lỗi này đến từ AbstractShip
dòng 65. Mở cái đó lên. Tôi muốn bạn nhìn vào 2 điều đặc biệt ở đây
dòng 1 - 4abstract class AbstractShip{. dòng 7 - 44hàm công khai setStrength[$number]{if [. is_numeric[$number]] {ném Ngoại lệ mới['Đã thông qua cường độ không hợp lệ '. $number];}$this->sức mạnh = $number;}. dòng 53 - 123}
Đầu tiên, chúng tôi lên kế hoạch trước. Khi chúng tôi tạo phương thức setStrength[]
, chúng tôi đã nói
Bạn biết gì?
Và thứ hai, để kích hoạt lỗi, chúng tôi đã đưa ra một ngoại lệ
dòng 1 - 4abstract class AbstractShip{. dòng 7 - 44hàm công khai setStrength[$number]{if [. is_numeric[$number]] {ném Ngoại lệ mới['Đã thông qua cường độ không hợp lệ '. $số];}. dòng 50 - 51}. dòng 53 - 123}
Và đó thực sự là những gì tôi muốn nói về. Ngoại lệ là các lớp, nhưng chúng hoàn toàn đặc biệt
Nhưng trước tiên, Exception
là một lớp PHP cốt lõi và khi chúng tôi thêm một namespace
vào tệp này, chúng tôi đã quên thay đổi nó thành \Exception
dòng 1 - 4abstract class AbstractShip{. dòng 7 - 44hàm công khai setStrength[$number]{if [. is_numeric[$number]] {ném \Exception mới['Đã thông qua cường độ không hợp lệ '. $số];}. dòng 50 - 51}. dòng 53 - 123}
Cái đó tốt hơn. Bây giờ hãy làm mới lại. Đây là một lỗi tốt hơn nhiều
Chưa bắt được
Exception
. Sức mạnh không hợp lệ đã vượt qua "chuối"
Khi có sự cố xảy ra, chúng tôi đưa ra các ngoại lệ. Tại sao? . nó dừng thực thi trang và ngay lập tức hiển thị cho chúng tôi một lỗi rất hay
Mẹo
Nếu bạn cài đặt tiện ích mở rộng XDebug, các thông báo ngoại lệ sẽ hữu ích hơn, đẹp hơn và sẽ sửa mã cho bạn [ok, phần cuối cùng đó là nói dối]
Thứ hai, ngoại lệ có thể bắt được. Đây là những gì có nghĩa là
Giả sử rằng tôi muốn giết trang ngay tại đây với một lỗi. Tôi thực sự có hai lựa chọn. Tôi có thể đưa ra một ngoại lệ hoặc tôi có thể in một số thông báo lỗi và sử dụng câu lệnh BrokenShip
0 để dừng thực thi
Nhưng khi bạn sử dụng câu lệnh BrokenShip
0, kịch bản của bạn đã thực sự hoàn thành. không có mã nào khác của bạn thực thi. Nhưng với một ngoại lệ, bạn thực sự có thể cố gắng phục hồi và tiếp tục
Hãy xem làm thế nào. Mở ra BrokenShip
2. Bên trong BrokenShip
3, đổi tên bảng thành BrokenShip
4
dòng 1 - 4 lớp PdoShipStorage triển khai Giao diện ShipStorage{. dòng 7 - 13public function fetchAllShipsData[]{$statement = $this->pdo->prepare['SELECT * FROM FOOOOO'];. dòng 17 - 19}. dòng 21 - 33}
Điều đó rõ ràng sẽ không hoạt động. Phương thức này được gọi bởi BrokenShip
5, bên trong BrokenShip
6
dòng 1 - 8class ShipLoader{. dòng 11 - 20public function getShips[]{. dòng 23 - 24$shipsData = $this->queryForShips[];. dòng 26 - 31}. dòng 33 - 60hàm riêng queryForShips[]{return $this->shipStorage->fetchAllShipsData[];}}
Khi chúng tôi cố gắng chạy cái này, chúng tôi nhận được một ngoại lệ
Không tìm thấy bảng cơ sở hoặc dạng xem
Lỗi đến từ BrokenShip
2 trên dòng 18, nhưng chúng ta cũng có thể thấy dòng gọi là this. BrokenShip
5 dòng 23
Bây giờ, điều gì sẽ xảy ra nếu chúng ta biết rằng đôi khi, vì lý do nào đó, một ngoại lệ như thế này có thể bị ném ra khi chúng ta gọi BrokenShip
3. Và khi điều đó xảy ra, chúng tôi không muốn tắt trang hoặc hiển thị lỗi. Thay vào đó, chúng tôi muốn - tạm thời - hiển thị trang không có tàu
Làm thế nào chúng ta có thể làm điều này? . Trong $brokenShip->setStrength[]
0, thêm $brokenShip->setStrength[]
1
dòng 1 - 8class ShipLoader{. dòng 11 - 60hàm riêng queryForShips[]{try {return $this->shipStorage->fetchAllShipsData[];} catch [\Exception $e] {. dòng 66 - 67}}}
Bây giờ, nếu phương thức BrokenShip
3 ném ra một ngoại lệ, trang sẽ không chết. Thay vào đó, mã bên trong $brokenShip->setStrength[]
0 sẽ được gọi và sau đó quá trình thực thi sẽ tiếp tục như bình thường
dòng 1 - 8class ShipLoader{. dòng 11 - 60private function queryForShips[]{try {return $this->shipStorage->fetchAllShipsData[];} catch [\Exception $e] {return [];}}}
Điều đó có nghĩa là, chúng ta có thể nói $brokenShip->setStrength[]
4
Và cứ như thế, trang hoạt động. Đó là sức mạnh của ngoại lệ. Khi bạn ném một ngoại lệ, bất kỳ mã nào gọi mã của bạn đều có cơ hội bắt ngoại lệ và nói
Không không không, tôi không muốn trang này chết. Thay vào đó, hãy làm một cái gì đó khác
Tất nhiên, có lẽ chúng tôi cũng không muốn điều này bị lỗi một cách âm thầm mà chúng tôi không biết, vì vậy bạn có thể gây ra lỗi và in thông báo cho nhật ký của chúng tôi. Lưu ý, tóm lại, chúng ta có quyền truy cập vào đối tượng Exception
và mọi ngoại lệ đều có phương thức $brokenShip->setStrength[]
6 trên đó. Sử dụng điều đó để kích hoạt lỗi đối với nhật ký của chúng tôi
dòng 1 - 8class ShipLoader{. dòng 11 - 60private function queryForShips[]{try {return $this->shipStorage->fetchAllShipsData[];} catch [\Exception $e] {trigger_error['Exception. '. $e->getMessage[]];return [];}}}
Được rồi, làm mới. Ngay bây giờ, chúng tôi thấy lỗi trên đầu trang. Nhưng đó chỉ là do cài đặt error_reporting của chúng tôi trong $brokenShip->setStrength[]
7. Khi sản xuất, điều này sẽ không hiển thị nhưng sẽ ghi một dòng vào nhật ký của chúng tôi