2009-03-16 23 views
46

Tôi đang chuyển từ mysql đơn giản sang php sang PDO và tôi nhận thấy rằng cách phổ biến để kiểm tra lỗi là sử dụng try/catch kết hợp thay vì nếu/else kết hợp.Lợi thế của việc sử dụng try {} catch {} so với if {} else {}

Lợi thế của phương pháp đó, tôi có thể sử dụng khối try/catch thay vì nhiều khối lồng nhau nếu xử lý tất cả các lỗi cho các bước khác nhau (kết nối, chuẩn bị, thực thi, v.v.)?

Trả lời

43

Tôi muốn sử dụng khối try/catch khi đường dẫn bình thường thông qua mã sẽ tiến hành mà không có lỗi trừ khi có một số điều kiện đặc biệt - như máy chủ bị hỏng, thông tin đăng nhập của bạn bị hết hạn hoặc không chính xác. Tôi sẽ không nhất thiết phải sử dụng nó để xử lý các lỗi không đặc biệt - nói như người dùng hiện tại không có vai trò chính xác. Đó là, khi bạn có thể mong đợi hợp lý và xử lý một lỗi mà không phải là một điều kiện đặc biệt, tôi nghĩ bạn nên làm kiểm tra của bạn.

Trong trường hợp bạn đã mô tả - thiết lập và thực hiện truy vấn, khối try/catch là một cách tuyệt vời để xử lý nó như bạn thường mong đợi truy vấn thành công. Mặt khác, có thể bạn sẽ muốn kiểm tra xem nội dung của kết quả là những gì bạn mong đợi với logic luồng điều khiển thay vì chỉ cố gắng sử dụng dữ liệu có thể không hợp lệ cho mục đích của bạn.

Một điều bạn muốn tìm kiếm là sử dụng thử/nắm bắt cẩu thả. Thử/nắm bắt không nên được sử dụng để bảo vệ bản thân khỏi chương trình xấu - "Tôi không biết điều gì sẽ xảy ra nếu tôi làm điều này vì vậy tôi sẽ quấn nó trong một thử/nắm bắt và hy vọng cho tốt nhất" lập trình. Thông thường, bạn sẽ muốn hạn chế các loại ngoại lệ bạn bắt gặp với các loại không liên quan đến chính mã (máy chủ bị hỏng, thông tin đăng nhập không hợp lệ, v.v.) để bạn có thể tìm và sửa các lỗi liên quan đến mã (con trỏ null, v.v. .).

+0

Cảm ơn rất nhiều! Ngoài sự tò mò, bạn sẽ xử lý như thế nào/đủ điều kiện truy vấn dẫn đến hàng trống khi bạn mong đợi dữ liệu (ví dụ: khi ai đó thay đổi thủ công một số trong chuỗi truy vấn)? – jeroen

+0

Phụ thuộc vào hoàn cảnh chính xác, nhưng nếu có thể truy vấn sẽ không trả về dữ liệu tôi chỉ cần kiểm tra nếu có dữ liệu (số đếm hàng! = 0) và trả về một thông báo "truy vấn không trả về kết quả". – tvanfosson

12

Nói chung, các khối try-catch là tuyệt vời vì chúng sẽ phá vỡ (di chuyển đến câu lệnh bắt) bất cứ khi nào ngoại lệ xảy ra. Nếu khối khác dựa vào bạn dự đoán khi nào thì lỗi sẽ xảy ra.

Chỉnh sửa: Ngoài ra, các khối catch sẽ không ngăn mã của bạn bị tạm dừng khi lỗi xảy ra.

+0

Điểm tốt (bắt không dừng mã khi tạm dừng khi xảy ra lỗi, đặc biệt nếu bạn xử lý loại ngoại lệ hẹp) –

5

Đó chính xác là lợi thế, sử dụng một lần thử/nắm bắt thay vì nhiều câu lệnh if. Bạn cũng sẽ có thể bắt được bất kỳ lỗi không lường trước được nào.

3

Vì PDO đang sử dụng các đối tượng, nên chúng đang tăng ngoại lệ nếu xảy ra lỗi. Các mysql cũ/mysqli là chức năng chỉ và không ném ngoại lệ họ chỉ đơn giản là trả về mã lỗi. Try/catch được sử dụng khi một ngoại lệ có thể được ném ra khỏi mã, và bạn nắm bắt nó trong mệnh đề catch, đây là một cách hướng đối tượng để xử lý các lỗi. Bạn không thể bắt ngoại lệ với các khối if/else - chúng không chia sẻ gì với try/catch.

+1

Tiện ích mở rộng Mysqli tiếp xúc cả API chức năng và OO. –

7

Thử/Bắt hoàn toàn tách logic xử lý lỗi khỏi logic nghiệp vụ đối tượng.

3

@Perchik:

triết lý chung của tôi về xử lý lỗi:

Bạn nên sử dụng if/else để xử lý tất cả các trường hợp, bạn mong đợi. Bạn nên không sử dụng try {} catch {} để xử lý mọi thứ (trong hầu hết các trường hợp) vì Ngoại lệ hữu ích có thể được nâng lên và bạn có thể tìm hiểu về sự hiện diện của lỗi từ nó. Bạn nên sử dụng try {} catch {} trong trường hợp bạn nghi ngờ điều gì đó có thể/sẽ bị lỗi và bạn không muốn nó làm hỏng toàn bộ hệ thống, như vấn đề truy cập hệ thống tệp thời gian chờ/tệp, tệp không tồn tại vv

Vexing exceptions

+0

Vâng, tôi đồng ý với bạn. Có lẽ tôi đã quá đơn giản. Try-catch chỉ nên được sử dụng khi một cái gì đó có thể đi sai và bạn không muốn nó giết chương trình của bạn. – Perchik

+0

"như thời gian chờ mạng/vấn đề truy cập hệ thống tệp" đó là ví dụ vàng ngay tại đó, xem xét cách chúng ta đang trở nên phụ thuộc vào nhiều máy chủ nói chuyện với một ứng dụng hoặc thậm chí là trang web .... – cartalot

5

Ném và bắt một ngoại lệ là một hoạt động tốn kém so với hầu hết mọi hoạt động nguyên thủy khác. Nếu đây là một đoạn mã cần thực hiện tốt (ví dụ, trong vòng lặp kín), bạn sẽ muốn xem xét trường hợp sử dụng của mình - nếu bạn mong đợi các ngoại lệ được ném tương đối thường xuyên, bạn sẽ tốt hơn nếu có/khác perforance-khôn ngoan (trừ khi các mã cơ bản chỉ là gói một ngoại lệ cho bạn, trong trường hợp đó không có được ở tất cả). Nếu các trường hợp ngoại lệ chỉ được ném trong trường hợp hiếm hoi, thì bạn nên dùng thử/nắm bắt để tránh chi phí phân nhánh trong một vòng lặp chặt chẽ.

7

Lợi thế của thử/nắm bắt và ngoại lệ nói chung là nhiều hơn cho mọi người phát triển thư viện như PDO. Chúng cho phép nhà phát triển hệ thống xử lý các tình huống không xác định hoặc kết quả không mong muốn một cách nhanh chóng và dễ dàng. Hãy kết nối cơ sở dữ liệu. Điều gì nên một hệ thống làm gì nếu cơ sở dữ liệu không thể đạt được. Nó có nên dừng thi hành không? Thử lại? Ném cảnh báo và tiếp tục? Các nhà phát triển hệ thống không thể biết những gì bạn sẽ cần nó để làm, họ họ ném một ngoại lệ, mà sau này bạn sẽ nắm bắt và xử lý.

Ưu điểm cho bạn, như một người tiêu dùng của hệ thống là thay vì nhận được một số mã lỗi mơ hồ trở lại, hoặc một boolean sai lầm rằng nó đã thất bại, bạn sẽ có một đối tượng ngoại lệ đơn giản mà sẽ

  1. Được đặt tên theo cách mà nó rõ ràng hơn những gì đã xảy ra (Nếu tôi nhớ đúng, PDO chỉ có một loại Ngoại lệ, nhưng các hệ thống khác chứa nhiều loại ngoại lệ cho các loại lỗi khác nhau)

  2. Có thể chứa các phương pháp và đặc tính có thể giúp bạn tìm ra lý do tại sao exc eption đã bị ném

Đó là lý thuyết. Có rất nhiều người thông minh tuyên bố Ngoại lệ là con đường để đi. Ngoài ra còn có rất nhiều người thông minh nghĩ rằng Ngoại lệ là ma quỷ, và một cái nạng cho các nhà phát triển hệ thống lười biếng. Không có gì giống như sự đồng thuận về vấn đề này.

0

Hoàn toàn đồng ý với @Jared Updike

Thường thì xử lý ngoại lệ được thực hiện với người dùng biết rất ít hoặc không có gì về nó. Mặt khác, người dùng của hệ thống biết về những gì xảy ra bên trong khối if-else.

ví dụ: Nó phải là mệnh đề "khác" hiển thị người dùng ATM, thông báo "Không đủ số dư ngân hàng" khi số dư của anh thấp. Và tin nhắn này KHÔNG THỂ được ngồi bên trong một khối "bắt" vì bất kỳ lý do nào !!

3

Ai cũng có câu trả lời tốt - nhưng tôi figured tôi sẽ ném của riêng tôi trong:

  1. try/catch là một cơ chế xử lý ngoại lệ thực tế - vì vậy nếu bạn thay đổi ngoại lệ của bạn, nó sẽ tự động làm việc trên tất cả các thử/câu lệnh bắt.
  2. Thử/Catch mang đến cơ hội chạy mã ngay cả trong trường hợp ngoại lệ lớn có thể giết chết if/else và ngoài ra, câu lệnh thử có thể được khôi phục (nếu bạn hiểu).
1

Trong php bằng cách sử dụng Try Catch with inheritence, Chúng tôi có thể ném ngoại lệ từ một lớp khác.

Ví dụ: - Tôi đang ở trong số controller và xác thực dữ liệu người dùng bằng cách sử dụng Models.

Nếu có bất kỳ lỗi nào xảy ra, tôi chỉ cần ném ngoại lệ từ các phương thức Model.

Việc thực hiện thử sẽ phá vỡ và bị chặn trong khối Catch.

Vì vậy, có ít chi phí trả lại giá trị bool và kiểm tra điều đó.

Ngoài việc này Try Catch hoạt động tuyệt vời Khi sử dụng trong chuỗi (Try - Catch bên trong một số Try - Catch) khác.

Các vấn đề liên quan