2015-08-10 15 views
10

Tôi đã chạy qua accidental usage của tiêu đề Status cho FastCGI. Có ưu/nhược điểm nào của việc sử dụng nó trong các tập lệnh độc lập với môi trường không?Chuyển hướng 301/302 độc lập với PHP

header('Location: ' . $url, true, 301); 

một mình gây ra không có vấn đề đối với tôi trên Apache 2.2 (theo phpinfo(), máy chủ sử dụng FastCGI).

Tập lệnh nhằm vào Apache và nginx (mod_php và FastCGI). Những gì sẽ thất bại giải pháp bằng chứng như thế nào?

+1

Câu hỏi hay. Tôi sẽ nghiêng về phía 'header ('HTTP/1.1 301'. $ Url, true, 301);' Có thể dư thừa? Bạn muốn xem mã cơ bản ngay bây giờ. Làm thế nào điều này tất cả các yếu tố trong việc sử dụng ['http_response_code'] (http://php.net/http_response_code) Tôi tự hỏi. – ficuscr

Trả lời

4

Mã trạng thái HTTP được phát ra như là một phần của dòng đầu tiên của phản hồi HTTP. Theo tiêu đề Fast CGI FAQ, tiêu đề Trạng thái là tiêu đề đặc biệt được máy chủ kiểm soát và kiểm soát dòng này và nó không được gửi cho máy khách. Tuy nhiên nếu nó được sử dụng với một bộ điều hợp máy chủ không FastCGI, giá trị được bỏ qua bởi máy chủ và tiêu đề có thể được gửi đi.

Giải pháp bạn đã có là cách độc lập với môi trường nhất có thể. Sự bổ sung duy nhất sẽ là câu lệnh exit ngay sau khi chuyển hướng để đảm bảo tập lệnh chấm dứt.

Hãy xem điều gì xảy ra dưới mui xe chặt chẽ hơn.

Việc chuyển hướng PHP mã sau

header('Location: ' . $url, true, 301); 
exit; 

sẽ gọi mã C trong ext/standard/head.c

PHP_FUNCTION(header) 
{ 
    [ code that just parses the arguments omitted ] 

    sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr); 
} 

nào đến lượt nó sẽ gọi sapi_header_op chức năng trong main/SAPI.c

[ ... ] 

switch (op) { 

    [ ... ] 

    case SAPI_HEADER_ADD: 
    case SAPI_HEADER_REPLACE: 
    case SAPI_HEADER_DELETE: { 
      sapi_header_line *p = arg; 

      if (!p->line || !p->line_len) { 
       return FAILURE; 
      } 
      header_line = p->line; 
      header_line_len = p->line_len; 
      http_response_code = p->response_code; 
      break; 
     } 

[ code that splits header line by colon, trims whitespace etc ] 

[ special headers handling code, including setting 302 if Location ] 

if (http_response_code) { 
    sapi_update_response_code(http_response_code); 
} 

sapi_header_add_op(op, &sapi_header); 
return SUCCESS; 

Nếu FastCGI lại -end đang được sử dụng, các tiêu đề được thêm vào sẽ là eventua lly được gửi đi bởi sapi_cgi_send_headers chức năng trong sapi/cgi/cgi_main.c

[ ... ] 
if (CGIG(nph) || SG(sapi_headers).http_response_code != 200) 
{ 
    [ emit status line if cgi.rfc2616-headers is set ] 

    [ Handle a case where there is a user supplied status line ] 

    [ Handle a case where there is already a user supplied status header ] 

    [ if none of the above ] 

     if (err->str) { 
      len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str); 
     } else { 
      len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code); 
     } 
    [ ... ] 
} 
[ ... ] 

Lưu ý rằng php_apache_sapi_send_headers chức năng trong sapi/apache2handler/sapi_apache2.c không có bất kỳ xử lý đặc biệt của Status tiêu đề vì nó không được sử dụng để giao tiếp module.

Vì vậy, bằng cách thực hiện các mã PHP trên

  1. mã phản hồi trong dòng trạng thái HTTP buộc phải 301
  2. Location tiêu đề hoặc là thêm hoặc hiện có được thay thế
  3. Các kịch bản thoát vì vậy không mã tiếp theo có thể thay đổi trạng thái hoặc tiêu đề

Tất cả các thao tác được thực hiện trong lớp SAPI là lớp trừu tượng trên bộ điều hợp máy chủ HTTP (FastCGI, Apa) che module etc). Đây là môi trường chéo và đáng tin cậy như nó được. Trong lịch sử đã có lỗi trong FastCGI ngăn cản 301 phản hồi hoạt động chính xác, tuy nhiên chúng được thực hiện trên máy chủ web và không có gì có thể được thực hiện từ mã PHP để giải quyết vấn đề.

Xem thêm:

+0

Đó là lời giải thích mà tôi đã bỏ lỡ. Cảm ơn bạn đã trả lời toàn diện được hỗ trợ bởi tài liệu tham khảo nguồn. – estus

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