2010-06-16 39 views
39

Tôi đang viết tập lệnh xác thực bằng PHP, được gọi là API, cần trả về 200 500` nếu không.Cách trả lại mã HTTP 500 trên bất kỳ lỗi nào, bất kể số

Vấn đề tôi đang gặp phải là php trả về 200 trong trường hợp điều kiện lỗi, thay vào đó xuất ra lỗi dưới dạng html. Làm thế nào tôi có thể chắc chắn rằng php sẽ trả về mã HTTP 500 trừ khi tôi trả lại chính xác HTTP 200 hoặc HTTP 403? Nói cách khác, tôi muốn biến bất kỳ và tất cả các điều kiện cảnh báo hoặc lỗi thành 500 s, không có ngoại lệ, sao cho trường hợp mặc định là từ chối yêu cầu xác thực và ngoại lệ là phê duyệt nó với mã 200.

Tôi đã chơi với set_error_handler()error_reporting(), nhưng cho đến nay không có may mắn. Ví dụ, nếu mã xuất ra một cái gì đó trước khi tôi gửi mã phản hồi HTTP, PHP tự nhiên báo cáo rằng bạn không thể sửa đổi thông tin tiêu đề sau khi xuất ra bất cứ thứ gì. Tuy nhiên, điều này được báo cáo bởi PHP dưới dạng mã phản hồi 200 với html giải thích sự cố. Tôi cần ngay cả loại điều này để được biến thành mã số 500.

Điều này có thể thực hiện được trong PHP không? Hay tôi cần phải làm điều này ở cấp độ cao hơn như sử dụng mod_rewrite bằng cách nào đó? Nếu đó là trường hợp, bất kỳ ý tưởng làm thế nào tôi muốn thiết lập đó?

+1

có một báo cáo lỗi cho điều này ở đây: http://bugs.php.net/bug.php?id=50921 - nó seams như nó có thể được sửa chữa. –

Trả lời

20

Tôi đã kiểm tra the PHP docs for header() và đơn giản hơn tôi đã tạo - nếu thông số thứ hai là đúng, nó sẽ thay thế tiêu đề tương tự. Mặc định là đúng. Vì vậy, hành vi chính xác là tiêu đề ('HTTP/1.1 403 Forbidden');, sau đó thực hiện logic xác thực, sau đó nếu nó xác thực, hãy làm tiêu đề ('HTTP/1.1 200 OK'). Nó sẽ thay thế đáp ứng 403, và sẽ đảm bảo rằng 403 là mặc định.

+0

Công việc tuyệt vời, đây là một giải pháp tuyệt vời. – tpow

63

Đơn giản chỉ cần gửi mã trạng thái như một phản ứng header():

header('HTTP/1.1 500 Internal Server Error'); 

Hãy nhớ rằng khi gửi tin nhắn này có phải không được bất kỳ đầu ra trước khi nó. Điều đó có nghĩa là không có các cuộc gọi echo và không có HTML hoặc khoảng trắng.

+5

Cũng nên nhớ rằng điều này sẽ không hoạt động nếu chạy như CGI, hoặc dưới IIS. –

+1

Cảm ơn - Tôi biết cách gửi mã phản hồi và tôi không biết gửi kết quả trước đó, như tôi đã đề cập trong câu hỏi của mình. Câu hỏi của tôi là làm thế nào để ngăn chặn PHP gửi một mã phản hồi 200 với các lỗi như html trong trường hợp lỗi. – Jake

+0

Gửi rồi xuất thông báo lỗi? Gửi một tiêu đề trạng thái báo cho PHP ghi đè lên mã phản hồi '200 OK' mặc định. – BoltClock

5
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); 

Bạn không nên sử dụng 500, biểu thị lỗi máy chủ nội bộ.

Điều này (và các tiêu đề khác) phải được gửi trước bất kỳ lưu lượng nào, ngoại trừ nếu bạn đã kích hoạt bộ đệm đầu ra.

+0

Cảm ơn bạn, nhưng đó không phải là câu hỏi của tôi. Tôi biết cách gửi mã phản hồi. Làm cách nào để ngăn PHP gửi mã 200 trong trường hợp lỗi? – Jake

+0

@Jake Nếu gửi phản hồi 403, nó sẽ không gửi 200. Tôi có thiếu gì đó không? – Artefacto

+0

Vấn đề là nếu nó chạy vào một điều kiện lỗi trước khi tôi biết có gửi một 403 0r 200, nó sẽ gửi 200 lỗi. Tôi muốn các hành vi ngược lại - Tôi muốn mặc định trong trường hợp của một lỗi là 403 hoặc 500 hoặc khá nhiều bất cứ điều gì khác hơn 200, vì vậy mà chỉ có tôi gửi một mã phản ứng 200. Tôi sẽ thử viết mã 403 ngay lập tức và sau đó ghi đè lên đó bằng 200 nếu mã thành công. Tôi không biết hành vi này được cho là gì trong trường hợp này. Có ai biết không? Nó sẽ ghi đè chính xác 403? – Jake

1

Sử dụng bộ đệm đầu ra để cho phép bạn sửa đổi tiêu đề sau khi ghi vào phần nội dung của trang. Bạn có thể thiết lập điều này trong ini file thay vì cập nhật mọi tập lệnh.

(Lưu ý gọi header() vẫn sẽ thất bại nếu bạn tuôn ra một cách rõ ràng các bộ đệm đầu ra)

C.

10

Trên trang php cho set_error_handler(), bạn có thể tìm thấy một bình luận bằng smp tại dot ncoastsoft . com đăng trên 08-Sep-2003 10:28 mà exlpains làm thế nào để thậm chí bắt lỗi chết người (mà bạn thường có thể không bắt với một lỗi xử lý tùy chỉnh tôi đã thay đổi mã cho bạn cần:

error_reporting(E_ALL); 
ini_set('display_errors', 'on'); 

function fatal_error_handler($buffer) { 
    header('HTTP/1.1 500 Internal Server Error'); 
    exit(0); 
} 

function handle_error ($errno, $errstr, $errfile, $errline){ 
    header('HTTP/1.1 500 Internal Server Error'); 
    exit(0); 
} 

ob_start("fatal_error_handler"); 
set_error_handler("handle_error"); 

//would normally cause a fatal error, but instead our output handler will be called allowing us to handle the error. 
somefunction(); 
ob_end_flush(); 

bắt shold này lỗi nghiêm trọng của hàm không tồn tại. s 500 và ngừng thực hiện phần còn lại của tập lệnh.

+0

Nó sẽ bắt bất kỳ lỗi nào nhưng phân tích lỗi. - Ngoài ra, nó sẽ ẩn dấu vết lỗi, vì vậy bạn cũng có thể đã vô hiệu hóa display_errors để có được chức năng tương tự. –

+0

@ThomasAhle bạn có thể tự tạo ra một dấu vết ngăn xếp sau khi bạn đặt tiêu đề – chacham15

1

Tò mò nếu bạn đã tìm ra cách lấy PHP trả về 500 lỗi phân tích cú pháp ... Tôi có cùng một nhu cầu chính xác ... API đang đăng lên ứng dụng của chúng tôi và dự kiến ​​chỉ 200 nếu mọi thứ được xử lý chính xác .. .

trong trường hợp của một lỗi Parse, PHP trả về một lỗi 200 và tôi đã sử dụng cả hai chức năng:

register_shutdown_function() set_error_handler()

và những không nhận được nhấn khi lỗi "phân tích cú pháp/cú pháp" xảy ra trong mã ...

Vì vậy, đây là một hàm PHP mức thấp sẽ phải được đặt trong PHP.INI hoặc ở đâu đó ... Tôi đang sử dụng PHP 5.3.10 ...

9

từ PHP 5.4.0 có một chức năng spezialized cho rằng http_response_code() ví dụ:

<?php 
    http_response_code(404); 
?> 

thấy http://www.php.net/manual/en/function.http-response-code.php

+1

Cảm ơn vì điều này! Tôi rất vui khi thấy PHP hiện là một hàm trợ giúp cho loại điều này. – renoirb

+0

Trong khi thuận tiện để biết, điều này không ngăn php trả lại 200 OK khi gặp lỗi. – Ellesedil

+0

chắc chắn, đó là không có thay thế cho lỗi 'xử lý', đó là lỗi' báo cáo' –

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