Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP

Xác thực và xử lý ngoại lệ: Từ UI đến Backend

by
Difficulty:IntermediateLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)

Sớm hay muộn trong sự nghiệp lập trình của bạn, bạn sẽ phải đối mặt với tình trạng tiến thoái lưỡng nan về xác nhận và xử lý ngoại lệ. Đây là trường hợp với tôi và nhóm của tôi. Một vài năm trước chúng tôi đã đạt đến một điểm khi chúng tôi phải thực hiện các hành động kiến trúc để đáp ứng tất cả các trường hợp đặc biệt mà dự án phần mềm khá lớn của chúng tôi cần xử lý. Dưới đây là danh sách các thực tiễn chúng tôi đã đưa ra giá trị và áp dụng khi nói đến xác nhận và xử lý ngoại lệ.


Xác nhận so với Xử lý ngoại lệ

Khi chúng tôi bắt đầu thảo luận về vấn đề của mình, một điều nổi lên rất nhanh. Xác nhận là gì và xử lý ngoại lệ là gì? Ví dụ: trong biểu mẫu đăng ký người dùng, chúng tôi có một số quy tắc cho mật khẩu (nó phải chứa cả số và chữ). Nếu người dùng chỉ nhập các chữ cái, đó là một vấn đề xác nhận hoặc ngoại lệ. UI có nên xác thực điều đó hay chỉ chuyển nó vào phần phụ trợ và nắm bắt bất kỳ trường hợp ngoại lệ nào mà tôi bị ném?

Chúng tôi đã đi đến một kết luận chung rằng xác thực đề cập đến các quy tắc được xác định bởi hệ thống và được xác minh đối với dữ liệu do người dùng cung cấp. Việc xác nhận không nên quan tâm đến cách thức hoạt động của logic nghiệp vụ hoặc cách hệ thống cho vấn đề đó hoạt động. Ví dụ, hệ điều hành của chúng tôi có thể mong đợi, mà không có bất kỳ sự phản đối nào, mật khẩu bao gồm các chữ cái đơn giản. Tuy nhiên, chúng tôi muốn thực thi kết hợp các chữ cái và số. Đây là một trường hợp để xác nhận, một quy tắc chúng tôi muốn áp đặt.

Mặt khác, các trường hợp ngoại lệ là trường hợp khi hệ thống của chúng tôi có thể hoạt động theo cách không dự đoán được, sai hoặc hoàn toàn không nếu một số dữ liệu cụ thể được cung cấp ở định dạng sai. Ví dụ, trong ví dụ trên, nếu tên người dùng đã tồn tại trên hệ thống, đó là trường hợp ngoại lệ. Logic nghiệp vụ của chúng tôi sẽ có thể đưa ra ngoại lệ thích hợp và UI bắt và xử lý nó để người dùng sẽ thấy một thông điệp hay.


Xác thực trong Giao diện người dùng

Bây giờ chúng tôi đã làm rõ mục tiêu của mình là gì, hãy xem một số ví dụ dựa trên cùng một ý tưởng biểu mẫu đăng ký người dùng.

Xác thực bằng JavaScript

Đối với hầu hết các trình duyệt ngày nay, JavaScript là bản chất thứ hai. Hầu như không có trang web nào mà không có một số mức độ JavaScript trong đó. Một thực hành tốt là xác thực một số điều cơ bản trong JavaScript.

Giả sử chúng ta có một mẫu đăng ký người dùng đơn giản trong tệp index.php, như được mô tả dưới đây.

Điều này sẽ xuất ra một cái gì đó tương tự như hình ảnh dưới đây:

RegistrationForm

Mỗi hình thức như vậy nên xác nhận rằng văn bản được nhập trong hai trường mật khẩu là bằng nhau. Rõ ràng điều này là để đảm bảo người dùng không mắc lỗi khi nhập mật khẩu của mình. Với JavaScript, việc xác thực khá đơn giản.

Đầu tiên chúng ta cần cập nhật một chút mã HTML của mình.

Chúng tôi đã thêm tên vào các trường nhập mật khẩu để chúng tôi có thể xác định chúng. Sau đó, chúng tôi đã chỉ định rằng khi gửi biểu mẫu sẽ trả về kết quả của hàm có tên validatePasswords(). Hàm này là JavaScript chúng ta sẽ viết. Các tập lệnh đơn giản như thế này có thể được giữ trong tệp HTML, các tập lệnh khác, phức tạp hơn sẽ có trong các tệp JavaScript của riêng chúng.

Điều duy nhất chúng tôi làm ở đây là so sánh các giá trị của hai trường đầu vào có tên là "password" và "confirm". Chúng ta có thể tham chiếu biểu mẫu theo tham số mà chúng ta gửi khi gọi hàm. Chúng tôi đã sử dụng "this" trong thuộc tính onsubmit của biểu mẫu, vì vậy chính biểu mẫu được gửi đến hàm.

Khi các giá trị là như nhau, true sẽ được trả về và biểu mẫu sẽ được gửi, nếu không, một thông báo cảnh báo sẽ được hiển thị cho người dùng biết mật khẩu không khớp.

PasswordDoNotMatchAlert

Xác thực HTML5

Mặc dù chúng tôi có thể sử dụng JavaScript để xác thực hầu hết các đầu vào của mình, nhưng có những trường hợp khi chúng tôi muốn đi trên một con đường dễ dàng hơn. Một số mức độ xác thực đầu vào có sẵn trong HTML5 và hầu hết các trình duyệt đều vui lòng áp dụng chúng. Sử dụng xác thực HTML5 đơn giản hơn trong một số trường hợp, mặc dù nó cung cấp ít linh hoạt hơn.

Để chứng minh một số trường hợp xác nhận, chúng tôi đã mở rộng hình thức của mình một chút. Chúng tôi đã thêm một địa chỉ email và một trang web cũng. Xác nhận HTML được đặt trên ba trường.

  • Username là bắt buộc. Nó sẽ xác nhận với bất kỳ chuỗi nào dài hơn 0 ký tự.
  • Trường địa chỉ email thuộc loại "email" và khi chúng tôi chỉ định thuộc tính "bắt buộc", trình duyệt sẽ áp dụng xác thực cho trường.
  • Cuối cùng, trường trang web thuộc loại "url". Chúng tôi cũng đã chỉ định một thuộc tính "mẫu" trong đó bạn có thể viết các biểu thức chính quy xác thực các trường bắt buộc.

Để làm cho người dùng nhận biết trạng thái của các trường, chúng tôi cũng sử dụng một ít CSS để tô màu các đường viền của đầu vào bằng màu đỏ hoặc xanh lục, tùy thuộc vào trạng thái xác thực được yêu cầu.

HTMLValidations

Vấn đề với xác nhận HTML là các trình duyệt khác nhau hoạt động khác nhau khi bạn cố gắng gửi biểu mẫu. Một số trình duyệt sẽ chỉ áp dụng CSS để thông báo cho người dùng, những trình duyệt khác sẽ ngăn chặn việc gửi biểu mẫu hoàn toàn. Tôi khuyên bạn nên kiểm tra xác thực HTML của mình một cách kỹ lưỡng trong các trình duyệt khác nhau và nếu cần cũng cung cấp dự phòng JavaScript cho những trình duyệt không đủ thông minh.


Xác thực trong các mô hình

Đến bây giờ, nhiều người biết về đề xuất kiến trúc sạch của Robert C. Martin, trong đó khung MVC chỉ dành cho trình bày và không dành cho logic kinh doanh.

HighLevelDesign

Về cơ bản, logic kinh doanh của bạn nên nằm ở một nơi tách biệt, tách biệt, được tổ chức để phản ánh kiến trúc của ứng dụng của bạn, trong khi các khung nhìn và bộ điều khiển của khung nên kiểm soát việc phân phối nội dung cho người dùng và các mô hình có thể được bỏ hoàn toàn hoặc, nếu cần , chỉ được sử dụng để thực hiện các hoạt động liên quan đến giao hàng. Một hoạt động như vậy là xác nhận. Hầu hết các khung có tính năng xác nhận tuyệt vời. Sẽ là một sự xấu hổ khi không đưa các mô hình của bạn vào công việc và xác nhận một chút ở đó.

Chúng tôi sẽ không cài đặt một số khung web MVC để trình bày cách xác thực các biểu mẫu trước đây của chúng tôi, nhưng đây là hai giải pháp gần đúng trong Laravel và CakePHP.

Xác nhận trong Mô hình Laravel

Laravel được thiết kế để bạn có nhiều quyền truy cập hơn vào xác thực trong Bộ điều khiển nơi bạn cũng có quyền truy cập trực tiếp vào đầu vào từ người dùng. Các loại trình xác nhận tích hợp sẵn thích được sử dụng ở đó. Tuy nhiên, có những gợi ý trên Internet rằng việc xác nhận hợp lệ trong các mô hình vẫn là một điều nên làm trong Laravel. Một ví dụ hoàn chỉnh và giải pháp của Jeffrey Way có thể được tìm thấy trên kho Github của anh ta.

Nếu bạn thích viết giải pháp của riêng mình, bạn có thể làm một cái gì đó tương tự như mô hình dưới đây.

Bạn có thể sử dụng điều này từ bộ điều khiển của mình bằng cách tạo đối tượng UserACL và gọi xác thực trên nó. Bạn có thể cũng sẽ có phương thức "đăng ký" trên mô hình này và đăng ký sẽ chỉ ủy thác dữ liệu đã được xác thực cho logic nghiệp vụ của bạn.

Xác nhận trong Mô hình CakePHP

CakePHP cũng thúc đẩy xác nhận trong các mô hình. Nó có chức năng xác nhận rộng rãi ở cấp độ mô hình. Đây là về cách xác thực cho biểu mẫu của chúng tôi sẽ trông như thế nào trong CakePHP.

Chúng tôi chỉ nêu gương một phần. Nó là đủ để làm nổi bật sức mạnh của xác nhận trong mô hình. CakePHP đặc biệt tốt trong việc này. Nó có một số lượng lớn các chức năng xác nhận tích hợp sẵn như "tối thiểu" trong ví dụ và nhiều cách khác nhau để cung cấp phản hồi cho người dùng. Thậm chí, các khái niệm như "bắt buộc" hoặc "allowEmpty" không thực sự là các quy tắc xác thực. Cake sẽ xem xét những điều này khi tạo chế độ xem của bạn và đặt các xác nhận HTML cũng trên các trường được đánh dấu bằng các tham số này. Tuy nhiên, các quy tắc rất hay và có thể dễ dàng được mở rộng chỉ bằng cách tạo các phương thức trên lớp mô hình như chúng ta đã làm để so sánh hai trường mật khẩu. Cuối cùng, bạn luôn có thể chỉ định thông báo bạn muốn gửi đến các chế độ xem trong trường hợp không xác thực. Thêm về xác nhận CakePHP trong sách dạy nấu ăn.

Xác nhận nói chung ở cấp độ mô hình có lợi thế của nó. Mỗi khung cung cấp dễ dàng truy cập vào các trường đầu vào và tạo cơ chế để thông báo cho người dùng trong trường hợp không xác thực. Không cần các câu lệnh thử bắt hoặc bất kỳ bước tinh vi nào khác. Xác nhận ở phía máy chủ cũng đảm bảo rằng dữ liệu được xác thực, không có vấn đề gì. Người dùng không thể lừa phần mềm của chúng tôi nữa như với HTML hoặc JavaScript. Tất nhiên, mỗi lần xác thực phía máy chủ đi kèm với chi phí cho một chuyến đi khứ hồi mạng và sức mạnh tính toán ở phía nhà cung cấp thay vì phía khách hàng.


Ném ngoại lệ từ logic kinh doanh

Bước cuối cùng trong việc kiểm tra dữ liệu trước khi đưa nó vào hệ thống là ở mức logic kinh doanh của chúng tôi. Thông tin đến phần này của hệ thống nên được vệ sinh đủ để có thể sử dụng được. Logic nghiệp vụ chỉ nên kiểm tra các trường hợp quan trọng đối với nó. Ví dụ: thêm một người dùng đã tồn tại là một trường hợp khi chúng ta đưa ra một ngoại lệ. Việc kiểm tra độ dài của người dùng có ít nhất năm ký tự không nên xảy ra ở cấp độ này. Chúng ta có thể giả định một cách an toàn rằng những hạn chế đó đã được thi hành ở cấp cao hơn.

Mặt khác, so sánh hai mật khẩu là một vấn đề để thảo luận. Ví dụ: nếu chúng ta chỉ mã hóa và lưu mật khẩu gần người dùng trong cơ sở dữ liệu, chúng ta có thể bỏ kiểm tra và giả sử các lớp trước đó đảm bảo mật khẩu bằng nhau. Tuy nhiên, nếu chúng tôi tạo người dùng thực trên hệ điều hành bằng API hoặc công cụ CLI thực sự yêu cầu tên người dùng, mật khẩu và xác nhận mật khẩu, chúng tôi có thể muốn nhận mục nhập thứ hai và gửi nó đến công cụ CLI. Hãy để nó xác nhận lại nếu mật khẩu khớp và sẵn sàng ném ngoại lệ nếu không. Bằng cách này, chúng tôi đã mô hình hóa logic kinh doanh của mình để phù hợp với cách hệ điều hành thực sự hoạt động.

Ném ngoại lệ từ PHP

Ném ngoại lệ từ PHP là rất dễ dàng. Hãy tạo lớp kiểm soát truy cập người dùng của chúng tôi và trình bày cách triển khai chức năng bổ sung người dùng.

Tôi luôn thích bắt đầu với một cái gì đó đơn giản giúp tôi đi. Tạo một bài kiểm tra ngu ngốc là một cách tuyệt vời để làm như vậy. Nó cũng buộc tôi phải suy nghĩ về những gì tôi muốn thực hiện. Một thử nghiệm có tên UserControlTest có nghĩa là tôi nghĩ rằng tôi sẽ cần một lớp UserControl để thực hiện phương thức của mình.

Bài kiểm tra tiếp theo để viết là một trường hợp thoái hóa. Chúng tôi sẽ không kiểm tra độ dài người dùng cụ thể, nhưng chúng tôi muốn đảm bảo rằng chúng tôi không muốn thêm người dùng trống. Đôi khi rất dễ để mất nội dung của một biến từ chế độ xem đến doanh nghiệp, trên tất cả các lớp ứng dụng của chúng tôi. Mã này rõ ràng sẽ thất bại, vì chúng tôi chưa có lớp.

Hãy tạo lớp và chạy thử nghiệm của chúng tôi. Bây giờ chúng tôi có một vấn đề khác.

Nhưng chúng ta cũng có thể khắc phục điều đó, chỉ trong vài giây.

Bây giờ chúng ta có thể có một lỗi thử nghiệm tốt đẹp cho chúng ta biết toàn bộ câu chuyện về mã của chúng ta.

Cuối cùng chúng ta có thể làm một số mã hóa thực tế.

Điều đó làm cho kỳ vọng vượt qua ngoại lệ, nhưng không chỉ định một thông báo, bài kiểm tra vẫn sẽ thất bại.

Đã đến lúc viết thông điệp của Ngoại lệ

Bây giờ, điều đó làm cho thử nghiệm của chúng tôi vượt qua. Như bạn có thể quan sát, PHPUnit xác minh rằng thông báo ngoại lệ dự kiến được chứa trong ngoại lệ thực sự bị ném. Điều này rất hữu ích vì nó cho phép chúng tôi tự động xây dựng các thông báo và chỉ kiểm tra phần ổn định. Một ví dụ phổ biến là khi bạn đưa ra một lỗi với một văn bản cơ sở và cuối cùng bạn chỉ định lý do cho ngoại lệ đó. Lý do thường được cung cấp bởi các thư viện hoặc ứng dụng của bên thứ ba.

Ném lỗi vào người dùng trùng lặp sẽ cho phép chúng tôi khám phá thông điệp này xây dựng thêm một bước nữa. Thử nghiệm ở trên tạo ra một giả lập sẽ mô phỏng một lệnh hệ thống, nó sẽ thất bại và theo yêu cầu, nó sẽ trả về một thông báo lỗi tốt. Chúng tôi sẽ tiêm lệnh này vào lớp UserControl để sử dụng nội bộ.

Việc tiêm một cá thể SystemCommand khá dễ dàng. Chúng tôi cũng đã tạo một lớp SystemCommand trong thử nghiệm của mình để tránh các vấn đề cú pháp. Chúng tôi sẽ không thực hiện nó. Phạm vi của nó vượt quá chủ đề của hướng dẫn này. Tuy nhiên, chúng tôi có một thông báo lỗi thử nghiệm khác.

Vâng. Chúng tôi không ném bất kỳ ngoại lệ. Logic để gọi lệnh hệ thống và cố gắng thêm người dùng bị thiếu.

Bây giờ, những sửa đổi cho phương thức add () có thể thực hiện thủ thuật. Chúng tôi cố gắng thực hiện lệnh của chúng tôi trên hệ thống, bất kể là gì, và nếu hệ thống nói rằng nó không thể thêm người dùng vì bất kỳ lý do gì chúng tôi đưa ra một ngoại lệ. Thông báo của ngoại lệ này sẽ là một phần được mã hóa cứng, với tên người dùng được đính kèm và sau đó là lý do từ lệnh hệ thống được nối vào cuối. Như bạn có thể thấy, mã này làm cho thử nghiệm của chúng tôi vượt qua.

Ngoại lệ tùy chỉnh

Ném ngoại lệ với các thông điệp khác nhau là đủ trong hầu hết các trường hợp. Tuy nhiên, khi bạn có một hệ thống phức tạp hơn, bạn cũng cần nắm bắt những ngoại lệ này và thực hiện các hành động khác nhau dựa trên chúng. Phân tích thông điệp của một ngoại lệ và chỉ hành động có thể dẫn đến một số vấn đề gây phiền nhiễu. Đầu tiên, chuỗi là một phần của UI, trình bày và chúng có tính chất dễ bay hơi. Dựa trên logic về việc thay đổi chuỗi sẽ dẫn đến cơn ác mộng quản lý phụ thuộc. Thứ hai, gọi phương thức getMessage () trên ngoại lệ bị bắt mỗi lần cũng là một cách lạ để quyết định làm gì tiếp theo.

Với tất cả những điều này, tạo ra các ngoại lệ của riêng chúng ta là bước hợp lý tiếp theo cần thực hiện.

Chúng tôi đã sửa đổi thử nghiệm của mình để mong đợi ngoại lệ tùy chỉnh của riêng mình, ExceptionCannotAddUser. Phần còn lại của bài kiểm tra là không thay đổi.

Lớp thực hiện ngoại lệ tùy chỉnh của chúng tôi giống như bất kỳ lớp nào khác, nhưng nó phải mở rộng Ngoại lệ. Sử dụng các ngoại lệ tùy chỉnh cũng cung cấp cho chúng tôi một nơi tuyệt vời để thực hiện tất cả các thao tác chuỗi liên quan đến bản trình bày. Di chuyển sự kết hợp ở đây, chúng tôi cũng loại bỏ việc trình bày khỏi logic kinh doanh và tôn trọng nguyên tắc trách nhiệm duy nhất.

Ném ngoại lệ của chúng ta chỉ là vấn đề thay đổi lệnh "ném" cũ sang lệnh mới và gửi hai tham số thay vì soạn tin nhắn ở đây. Tất nhiên tất cả các bài kiểm tra đang qua.

Bắt ngoại lệ trong MVC của bạn

Các ngoại lệ phải được bắt gặp tại một số điểm, trừ khi bạn muốn người dùng của bạn nhìn thấy chúng như hiện tại. Nếu bạn đang sử dụng một khung công tác MVC, có lẽ bạn sẽ muốn bắt ngoại lệ trong bộ điều khiển hoặc mô hình. Sau khi ngoại lệ được bắt, nó được chuyển đổi trong một thông báo cho người dùng và được hiển thị bên trong chế độ xem của bạn. Một cách phổ biến để đạt được điều này là tạo phương thức "tryAction ($ action)" trong bộ điều khiển hoặc mô hình cơ sở của ứng dụng của bạn và luôn gọi nó bằng hành động hiện tại. Trong phương pháp đó, bạn có thể thực hiện logic bắt và tạo thông điệp tốt cho phù hợp với khung của bạn.

Nếu bạn không sử dụng khung web hoặc giao diện web cho vấn đề đó, lớp trình bày của bạn sẽ đảm bảo nắm bắt và chuyển đổi các ngoại lệ này.

Nếu bạn phát triển một thư viện, nắm bắt các ngoại lệ của bạn sẽ là trách nhiệm của khách hàng của bạn.


Tổng kết

Đó là nó. Chúng tôi đi qua tất cả các lớp của ứng dụng của chúng tôi. Chúng tôi xác nhận bằng JavaScript, HTML và trong các mô hình của chúng tôi. Chúng tôi đã ném và bắt ngoại lệ từ logic kinh doanh của chúng tôi và thậm chí tạo ra các ngoại lệ tùy chỉnh của riêng chúng tôi. Cách tiếp cận này để xác nhận và xử lý ngoại lệ có thể được áp dụng từ các dự án nhỏ đến lớn mà không có bất kỳ vấn đề nghiêm trọng nào. Tuy nhiên, nếu logic xác thực của bạn đang trở nên rất phức tạp và các phần khác nhau trong dự án của bạn sử dụng các phần logic chồng chéo, bạn có thể xem xét trích xuất tất cả các xác thực có thể được thực hiện ở cấp cụ thể cho dịch vụ xác thực hoặc nhà cung cấp xác thực. Các mức này có thể bao gồm, nhưng không cần giới hạn ở trình xác thực JavaScript, trình xác thực PHP phụ trợ, trình xác thực giao tiếp của bên thứ ba, v.v.

Cảm ơn bạn đã đọc. Chúc một ngày tốt lành.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.