Làm cách nào để kiểm tra tiêu đề từ phản hồi trong PHP?

Tiêu đề HTTP rất quan trọng để trao đổi thông tin giữa trình duyệt và máy chủ. Chúng có hai loại - tiêu đề yêu cầu và tiêu đề phản hồi. Bài viết này bao gồm các tiêu đề phản hồi

Làm cách nào để kiểm tra tiêu đề từ phản hồi trong PHP?

Cách gửi tiêu đề phản hồi HTTP

Vì các tiêu đề phản hồi được gửi bởi máy chủ, nên cần phải sử dụng các công cụ ngôn ngữ lập trình, ví dụ: các cơ sở PHP. Nó có các chức năng đặc biệt để làm việc với các tiêu đề. Để gửi tiêu đề - chức năng tiêu đề

Bạn chỉ có thể gửi tiêu đề nếu chưa có dữ liệu nào được gửi. Trước khi gọi chức năng này, không được có thẻ HTML, dòng trống, v.v. , bao gồm trong các tập tin bao gồm. Nghĩa là, các tiêu đề được gửi trước, sau đó là chính dữ liệu

Ví dụ gửi tiêu đề tới PHP tới trình duyệt

  header ('HTTP / 1.1 404 Not Found');
header ('Status: 404 Not Found');
header ('Location: https: // example.com');  

Cách nhận tiêu đề phản hồi HTTP

Các chức năng sau đây có sẵn cho việc này

  • get_headers - trả về tất cả các tiêu đề từ phản hồi của máy chủ đối với yêu cầu HTTP;
  • apache_response_headers - Trả về danh sách tất cả các tiêu đề phản hồi HTTP của Apache;
  • http_response_code - nhận hoặc đặt mã phản hồi HTTP;
  • headers_list - Trả về danh sách các tiêu đề đã gửi (hoặc sẵn sàng gửi)

Bạn cũng có thể sử dụng thư viện CURL. Làm cách nào để nhận tiêu đề phản hồi bằng CURL?

  if ($ curl = curl_init ('https://example.com')) {
curl_setopt ($ curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ curl, CURLOPT_NOBODY, true);
curl_setopt ($ curl, CURLOPT_HEADER, true);
$ out = curl_exec ($ curl);
echo $ out;
curl_close ($ curl);
}  

Cách xóa tiêu đề phản hồi HTTP

Có thể xóa tiêu đề bằng chức năng đặc biệt - header_remove. Trước tiên, bạn cần kiểm tra xem các tiêu đề đã được gửi chưa

  if (! headers_sent ()) {
    header_remove ('Content-Type');
}  

Như bạn có thể thấy từ bài viết, rất dễ làm việc với các tiêu đề phản hồi HTTP ở phía máy chủ

Khi sử dụng file_get_contents để thực hiện các yêu cầu HTTP, các tiêu đề phản hồi của máy chủ được lưu trữ trong một biến dành riêng sau mỗi yêu cầu thành công;

2291 lượt xem

Làm cách nào để kiểm tra tiêu đề từ phản hồi trong PHP?

Bởi. Jacob

Đã chỉnh sửa. 2022-03-18 11. 51

Làm cách nào để kiểm tra tiêu đề từ phản hồi trong PHP?

Khi bạn đang sử dụng các hàm tệp PHP dựng sẵn để thực hiện các yêu cầu HTTP, các tiêu đề phản hồi sẽ tự động được cung cấp trong một biến đặc biệt, $http_response_header; . Trong hướng dẫn này, bạn sẽ học cách phân tích cú pháp các tiêu đề yêu cầu bất kể bạn đang sử dụng cURL hay các hàm tệp như file_get_contents

Hơi lạ là các tiêu đề được lưu trữ dưới dạng một mảng được lập chỉ mục, thay vì một mảng kết hợp thân thiện với người dùng hơn;

Để phân tích các tiêu đề phản hồi và tạo một mảng kết hợp, chúng ta có thể sử dụng giải pháp này cho các hàm tệp tích hợp

$response_headers = [];
$status_message = array_shift($http_response_header);
foreach ($http_response_header as $value) {
  if(false !== ($matches = explode(':', $value, 2))) {
    $response_headers["{$matches[0]}"] = trim($matches[1]);
  }                
}

Và cái này khi sử dụng thư viện cURL

// Define the $response_headers array for later use
$response_headers = [];

// Get the first line (The Status Code)
$line = strtok($headers, "\r\n");
$status_code = trim($line);

// Parse the string, saving it into an array instead
while (($line = strtok("\r\n")) !== false) {
    if(false !== ($matches = explode(':', $line, 2))) {
      $response_headers["{$matches[0]}"] = trim($matches[1]);
    }  
}

Làm điều này giúp bạn có thể dễ dàng kiểm tra xem một tiêu đề đã cho có tồn tại hay không, chỉ đơn giản bằng cách sử dụng isset trên khóa mảng

if (isset($response_headers["content-type"])) {
  echo '

The "content-type" header was found, and the content is:

'
; echo $response_headers["content-type"]; exit(); }

tập tin chức năng

Như đã đề cập trước đó, để có được các tiêu đề phản hồi bằng cách sử dụng các hàm tệp dựng sẵn của PHP, bạn có thể lặp qua biến $http_response_header;

Các chức năng được sử dụng để thực hiện các yêu cầu HTTP bằng cách sử dụng các hàm tệp thường bao gồm file_get_contents, stream_context_create và stream_get_contents — cách sử dụng chúng sẽ được trình bày trong các hướng dẫn khác

Phần tử đầu tiên trong mảng $http_response_header luôn là mã trạng thái HTTP — ngay cả khi đọc các tiêu đề thô, mã trạng thái luôn xuất hiện trước. Có thể hữu ích khi lưu trữ mã trạng thái trong một biến riêng biệt

$status_message = array_shift($http_response_header);

Hàm array_shift phục vụ hai mục đích ở đây

  1. Nó trả về phần tử đầu tiên trong mảng
  2. Nó loại bỏ phần tử đầu tiên khỏi mảng

Tất cả các khóa dãy số cũng sẽ được cập nhật tương ứng, vì vậy sẽ không có bất kỳ khóa nào bị thiếu

Các tiêu đề HTTP được tạo bởi khóa. cặp giá trị, nhưng chúng ta không thể chuyển đổi chúng thành một mảng bằng dấu hai chấm (. ), vì các giá trị tiêu đề cũng có thể chứa dấu hai chấm. Vì vậy, những gì chúng ta có thể làm, mà không cần dùng đến biểu thức chính quy, là tách chuỗi theo dấu hai chấm đầu tiên trong chuỗi, vì dấu hai chấm luôn xuất hiện sau tên khóa

Ghi chú. Mặc dù sử dụng biểu thức chính quy sẽ dễ dàng hơn, nhưng sẽ nhanh hơn khoảng 10% đến 68% nếu sử dụng kết hợp giữa sọc và chất nền hoặc phát nổ - điều đó không quan trọng lắm trong thực tế - tuy nhiên, tôi nghĩ chúng ta nên tuân theo những gì

Tất cả các cách tiếp cận sau đây thực sự khá dễ sử dụng, vì vậy nên sử dụng cách nào có lẽ nên tùy theo cách nào hiệu quả nhất

Giải pháp 1

Sử dụng chức năng phát nổ nhanh hơn khoảng 68% so với sử dụng preg_match

$headers = array();
$status_message = array_shift($http_response_header);
foreach ($http_response_header as $value) {
  if(false !== ($matches = explode(':', $value, 2))) {
    $headers["{$matches[0]}"] = trim($matches[1]);
  }                
}

Giải pháp 2

Đây là cách sử dụng stripos và substr, nhanh hơn khoảng 10% so với sử dụng biểu thức chính quy

________số 8_______

Giải pháp 3

Nếu vì lý do nào đó bạn thích sử dụng cụm từ thông dụng hơn, vui lòng làm như vậy; . Đây là cách sử dụng preg_match để làm điều tương tự

$headers = array();
$status_message = array_shift($http_response_header);
foreach ($http_response_header as $value) {
  if (preg_match('/^([^:]+):([^\n]+)/', $value, $matches)) {
    $headers["{$matches[1]}"] = trim($matches[2]);
  }  
}
print_r($headers);

Tất nhiên chúng ta cũng có thể loại bỏ hàm trim khi sử dụng biểu thức chính quy;

Cách điểm chuẩn được thực hiện

Mỗi bài kiểm tra được thực hiện bằng cách phân tích cú pháp các tiêu đề 1 triệu lần như thế này

$start_time = microtime(true);
$repeat = 0;
$status_message = array_shift($http_response_header);
while ($repeat < 1000000) {
  $headers = array();
  $status_message = array_shift($http_response_header);
  foreach ($http_response_header as $value) {
    if(false !== ($matches = explode(':', $value, 2))) {
      $headers["{$matches[0]}"] = trim($matches[1]);
    }
  }
  ++$repeat;
}
$end_time = microtime(true);
echo $end_time - $start_time . "\n\n";
var_dump($headers);exit();

Xoăn

Việc lấy các tiêu đề phản hồi bằng cURL khó khăn hơn vì chúng sẽ không có sẵn ngay lập tức, không giống như khi bạn sử dụng các hàm tệp tích hợp sẵn. Thay vào đó, chúng tôi sẽ phải trích xuất thủ công các tiêu đề từ yêu cầu. Điều này có thể được thực hiện với hàm curl_getinfo, sau khi thực hiện một yêu cầu

$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $header_size);
$body = substr($response, $header_size);

Các tiêu đề sau đó được lưu trữ dưới dạng một chuỗi trong biến $headers

Để tạo một mảng kết hợp từ chuỗi, bạn có thể lặp qua từng dòng trong chuỗi, lưu nội dung của nó vào mảng khi bạn thực hiện

// Define the $response_headers array for later use
$response_headers = [];

// Get the first line (The Status Code)
$line = strtok($headers, "\r\n");
$status_code = trim($line);

// Parse the string, saving it into an array instead
while (($line = strtok("\r\n")) !== false) {
    if(false !== ($matches = explode(':', $line, 2))) {
      $response_headers["{$matches[0]}"] = trim($matches[1]);
    }  
}

Cập nhật dựa trên ý kiến ​​​​của bạn

Tôi đã thử nghiệm nhiều tình huống khác nhau khi phân tích cú pháp các tiêu đề cURL thô và tôi đã thực hiện thử nghiệm sau. Thử nghiệm này vẫn đang được tiến hành, nhưng có thể hữu ích cho một số người làm theo, ngay cả ở trạng thái ban đầu hiện tại. Mình bận công việc nên chưa có thời gian làm hết bài test này

Rõ ràng các tiêu đề HTTP đã từng có thể chuyển sang dòng tiếp theo, mặc dù điều này không được khuyến khích. Tôi không biết liệu đây có phải là sự cố khi dựa vào $http_response_headers có sẵn của PHP hay không, nhưng có thể xảy ra khi sử dụng cURL. Tôi chưa kiểm tra điều đó. Các dòng tiêu đề dài hơn 1024 ký tự sẽ bị bỏ qua theo php. net

Mã kiểm tra sau đây dành cho cURL và phải tính đến các dòng gấp cũng như tiêu đề không có tên (tiêu đề chỉ bắt đầu bằng ". ". Tôi có thể sẽ quay lại tinh chỉnh điều này sau nếu cần

// Define the $response_headers array for later use
$response_headers = [];

// Get the first line (The Status Code)
$line = strtok($headers, "\r\n");
$status_code = trim($line);

// Parse the string, saving it into an array instead
while (($line = strtok("\r\n")) !== false) {
    if(false !== ($matches = explode(':', $line, 2))) {
      $response_headers["{$matches[0]}"] = trim($matches[1]);
    }  
}
0

Phần kết luận

Trong thực tế, việc chúng ta sử dụng hàm chuỗi hay biểu thức chính quy dường như không quan trọng lắm — ít nhất là không dành cho những thứ đơn giản như thế này. Nhưng tôi vẫn khuyên bạn nên sử dụng những gì được biết là tùy chọn nhanh nhất

Trong trường hợp này, không có chức năng cắt, sử dụng preg_match chỉ chậm hơn khoảng 10% so với dải và chất nền — nhưng chậm hơn 68% so với sử dụng phát nổ

Mặc dù điều này có vẻ rất nhiều — và trong một số trường hợp — chúng ta nên nhớ rằng các bài kiểm tra điểm chuẩn thường sẽ thực thi một tập lệnh hơn một triệu lần để có được bức tranh rõ ràng hơn. Điều này có nghĩa là chúng tôi sẽ cần hàng trăm hoặc hàng nghìn người dùng đồng thời trước khi chúng tôi nhận thấy bất kỳ sự khác biệt có ý nghĩa nào

Tuy nhiên, cá nhân tôi sẽ luôn chọn giải pháp mà tôi biết là nhanh hơn, đặc biệt là khi các giải pháp đó rất dễ thực hiện. preg_match sẽ chỉ dễ đọc hơn nếu nhà phát triển hiểu các biểu thức chính quy;

Làm cách nào để kiểm tra các tiêu đề trong PHP?

PHP. Hàm get_headers() .

Làm cách nào để nhận các tiêu đề yêu cầu trong PHP?

Nhận được tiêu đề yêu cầu, máy chủ web sẽ gửi lại tiêu đề phản hồi HTTP cho máy khách. Đọc bất kỳ tiêu đề yêu cầu nào. Có thể đạt được điều này bằng cách sử dụng hàm getallheaders() . ví dụ 2. Nó có thể đạt được bằng cách sử dụng hàm apache_request_headers().

Làm cách nào để xem các tiêu đề tôi đã gửi?

Hàm headers_sent() là một hàm có sẵn trong PHP dùng để xác định xem tiêu đề có được gửi thành công hay không. Hàm headers_sent() trả về True nếu tiêu đề được gửi thành công và Sai nếu ngược lại.