Hướng dẫn log exception php - đăng nhập ngoại lệ php
Giới thiệuThông thường, chúng ta trong quá trình viết code đều không thể lường trước được mọi kịch bản lỗi có thể xảy ra. Nếu có sự cố xảy ra, Laravel sẽ trả về thông báo "Whoops, something went wrong" hoặc tệ hơn là trang báo lỗi để lộ source code. Điều này gây ra trải nghiệm không tốt cho người dùng trên môi trường product. Vì vậy bài viết này mình muốn giới thiệu đến các bạn kỹ thuật xử lý ngoại lệ Exceptions trong Laravel. Lý thuyết thì luôn nhàm chán với một đống định nghĩa và giải thích khó nhằn cho nên mình sẽ đưa ra 1 ví dụ để các bạn dễ hình dung. Let's go!!! Show 1. Ví dụ: Chức năng tìm kiếm UserMột ví dụ đơn giản là xây dựng chức năng tìm kiếm User thông qua ID và chúng ta hãy đi từng bước nhé. Trước tiên hãy chạy seed để tạo dữ liệu mẫu cho quá trình test.
Tiếp theo, ta có 2 routes:
Tương ứng với 2 methods trong controller:
Không thể thiếu file view rồi:
Chúng ta xem kết quả tý nào: Ngon rồi! Tiếp đến là view users.search nhé, view này sẽ có đường dẫn là resources/views/users/search.blade.php:resources/views/users/search.blade.php:
Chúng ta search thử 1 User nhé, ID = 10 đi rồi xem kết quả nào Đến lúc này mọi thứ đều khá bảnh à nhầm khá ổn. Nhưng nếu user không tồn tại thì sao nhỉ? 2. Xử lý ngoại lệNăm nay là 2019, chúng ta search thử ID = 2019 xem sao Ooops, trông có chán không cơ chứ? Có 1 cách nhanh chóng để che giấu lỗi này đi, ta có thể thực hiện bằng cách vào file .env và set APP_DEBUG = false sau đó trình duyệt trả về trang thông lỗi có code = 500 với 1 message "Whoops, something went wrong on our servers.". Điều này không cung cấp bất kỳ thông tin có giá trị nào cho người dùng trong thực tế..env và set APP_DEBUG = false sau đó trình duyệt trả về trang thông lỗi có code = 500 với 1 message "Whoops, something went wrong on our servers.". Điều này không cung cấp bất kỳ thông tin có giá trị nào cho người dùng trong thực tế. Laravel cung cấp 1 cách khác cũng nhanh không kém là sử dụng function findOrFail() thay vì find(). Với cách này, Laravel sẽ hiển thị page 404 với dòng text "Sorry, the page you are looking for could not be found." Page 404 này mặc định cho toàn bộ dự án nên việc custom lại view sẽ không phù hợp với từng chức năng riêng biệt.findOrFail() thay vì find(). Với cách này, Laravel sẽ hiển thị page 404 với dòng text "Sorry, the page you are looking for could not be found." Page 404 này mặc định cho toàn bộ dự án nên việc custom lại view sẽ không phù hợp với từng chức năng riêng biệt. Vì vậy tối ưu nhất chỉ có thể là sử dụng try catch để xử lý Exception và chuyển hướng trở lại form tìm kiếm với 1 error message dễ hiểu. Chúng ta cần biết loại ngoại lệ và tên lớp mà nó sẽ trả về. Trong trường hợp findOrFail(), nó sẽ ném ra 1 Eloquent exception có tên là ModelNotFoundException, lúc này controller đã thay đổi:try catch để xử lý Exception và chuyển hướng trở lại form tìm kiếm với 1 error message dễ hiểu. Chúng ta cần biết loại ngoại lệ và tên lớp mà nó sẽ trả về. Trong trường hợp findOrFail(), nó sẽ ném ra 1 Eloquent exception có tên là ModelNotFoundException, lúc này controller đã thay đổi:
Thêm hiển thị error ở file view index.blade.php:
Chạy thử xem sao nhé: Exception bắn ra 1 error message mặc định. Nếu bạn muốn custom lại message theo ý mình thì đơn giản thôi: 53. Sử dụng Services để xử lý Error MessageChúng ta đã lấy 1 ví dụ hết sức đơn giản nhưng trong thực tế, ứng dụng ngày càng phình to và điều tất yếu là controller ngày càng gánh quá nhiều chức năng làm cho nó trở nên cồng kềnh và khó maintain, nâng cấp. Vì thế việc sử dụng 1 số Design pattern vào trong ứng dụng là cần thiết. Thường thì controller sẽ gọi service từ bên ngoài vào và cụ thể trong trường hợp này, nó sẽ không đảm nhận công việc custom error message. Ta sẽ sử dụng Services Layer để xử lý Error Message.controller ngày càng gánh quá nhiều chức năng làm cho nó trở nên cồng kềnh và khó maintain, nâng cấp. Vì thế việc sử dụng 1 số Design pattern vào trong ứng dụng là cần thiết. Thường thì controller sẽ gọi service từ bên ngoài vào và cụ thể trong trường hợp này, nó sẽ không đảm nhận công việc custom error message. Ta sẽ sử dụng Services Layer để xử lý Error Message. Tạo folder app/Services sau đó là file class UserService:
Tiếp theo ở controller chúng ta cần gọi service này.Đầu tiên, ta đưa nó vào phương thức construct () :construct () :
Nếu bạn chưa biết về kỹ thuật Dependency Injection và cách thức hoạt động của Laravel IoC container thì hãy tham khảo bài viết này:
Đến lúc này method search() cũng đã thay đổi:search() cũng đã thay đổi:
4. Cách Exception họat động trong LaravelTất cả các exception được xử lý bởi class App\Exceptions\Handler. Chúng ta cùng xem bên trong nó sẽ chứa những gì:exception được xử lý bởi class App\Exceptions\Handler. Chúng ta cùng xem bên trong nó sẽ chứa những gì:
5. Tạo ExceptionCác Exception mà Laravel cung cấp sẵn đôi khi không đáp ứng đủ nhu cầu giải quyết vấn đề của chúng ta. Vì vậy, Laravel cho phép tự tạo Exception bằng câu lệnh (mình sẽ tiếp tục sử dụng ví dụ ở phía đầu bài viết cho phần này):
Exception sẽ được tạo ra và xem trong đó thì ta sẽ không thấy gì cả nhưng giống như class App\Exceptions\Handler, chúng ta sẽ thêm vào 2 method report và render. Điều này giúp chúng ta thay vì kiểm tra các loại exception trong phương thức report và render của Handler, ta có thể định nghĩa trong tùy chỉnh exception của bạn. Khi các phương thức đó tồn tại, chúng có thể tự động được gọi đến bằng framework:App\Exceptions\Handler, chúng ta sẽ thêm vào 2 method report và render. Điều này giúp chúng ta thay vì kiểm tra các loại exception trong phương thức report và render của Handler, ta có thể định nghĩa trong tùy chỉnh exception của bạn. Khi các phương thức đó tồn tại, chúng có thể tự động được gọi đến bằng framework: 0Bây giờ, khi có Exception được bắn ra thì sẽ trả về view thông báo lỗi: 1Đừng quên sửa lại một chút ở bên Service nhé: 2Controller nữa, lúc này method search sẽ trông như thế này: 3Chạy thử ví dụ để xem kết quả nhé: Ngon lành rồi đúng không các bạn? Tổng kếtBài viết khá dài vì vậy cảm ơn bạn đã đọc đến đây. Mình mong rằng với bài viết này các bạn sẽ hiểu và biết cách xử lý ngoại lệ trong Laravel. Nếu có sai sót hoặc nhầm lẫn các bạn có thể comment ở phía dưới nhé. Cảm ơn các bạn rất nhiều!!! Nguồn tham khảo:
|