2010-12-14 44 views

Trả lời

24

Bạn có thể sử dụng get_headers($url)

Ví dụ 2 từ Manual:

<?php 
// By default get_headers uses a GET request to fetch the headers. If you 
// want to send a HEAD request instead, you can do so using a stream context: 
stream_context_set_default(
    array(
     'http' => array(
      'method' => 'HEAD' 
     ) 
    ) 
); 
print_r(get_headers('http://example.com')); 

// gives 
Array 
(
    [0] => HTTP/1.1 200 OK 
    [Date] => Sat, 29 May 2004 12:28:14 GMT 
    [Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux) 
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT 
    [ETag] => "3f80f-1b6-3e1cb03b" 
    [Accept-Ranges] => bytes 
    [Content-Length] => 438 
    [Connection] => close 
    [Content-Type] => text/html 
) 

Các phần tử mảng đầu tiên sẽ chứa các mã trạng thái HTTP Response. Bạn phải phân tích cú pháp đó.

Lưu ý rằng chức năng get_headers trong ví dụ sẽ đưa ra yêu cầu HEAD HTTP, có nghĩa là nó sẽ không tìm nạp nội dung của URL. Điều này hiệu quả hơn việc sử dụng yêu cầu GET cũng sẽ trả về cơ thể. Cũng cần lưu ý rằng bằng cách đặt một ngữ cảnh mặc định mặc định, bất kỳ cuộc gọi nào tiếp theo sử dụng ngữ cảnh luồng http, giờ đây sẽ phát hành yêu cầu HEAD. Vì vậy, hãy chắc chắn để thiết lập lại bối cảnh mặc định để sử dụng GET một lần nữa khi thực hiện.

PHP cũng cung cấp variable $http_response_header

Mảng $http_response_header cũng tương tự như get_headers() chức năng. Khi sử dụng HTTP wrapper, $http_response_header sẽ được điền bằng tiêu đề phản hồi HTTP. $http_response_header sẽ được tạo trong phạm vi địa phương.

Nếu bạn muốn tải xuống nội dung của tài nguyên từ xa, bạn không muốn thực hiện hai yêu cầu (một tài nguyên để xem tài nguyên tồn tại và một để tìm), nhưng chỉ một. Trong trường hợp đó, hãy sử dụng một cái gì đó như file_get_contents để tìm nạp nội dung và sau đó kiểm tra các tiêu đề từ biến.

+0

Liên quan: [Làm cách nào để kiểm tra xem tệp từ xa có tồn tại bằng PHP không?] (Http://stackoverflow.com/questions/981954/how-can-one-check-to-see-if -a-remote-file-exist-using-php) (thông qua: [HEAD đầu tiên với PHP Streams] (http://hakre.wordpress.com/2011/09/17/head-first-with-php-streams/)) – hakre

+0

Thêm ký tự @ vào đầu để chặn cảnh báo php khi url được kiểm tra không tồn tại. Bằng cách đó bạn có thể ném ngoại lệ tùy chỉnh của riêng bạn. –

+1

@FranciscoLuz Tôi xem xét việc sử dụng triệt tiêu lỗi một cách không có lợi và ưu tiên sử dụng trình xử lý lỗi thích hợp. – Gordon

0

@Gordon - Đây là một thói quen thư viện hoàn chỉnh hơn dựa trên câu trả lời của bạn. Nó bao gồm một số kiểm tra sơ bộ về tính hợp lệ của URL, xử lý lỗi nhiều hơn và phân tích cú pháp các tiêu đề được trả lại. Nó cũng tuân theo bất kỳ chuỗi chuyển hướng nào cho một số bước hợp lý.

class cLib { 
    static $lasterror = 'No error set yet'; 
    /** 
    * @brief See with a URL is valid - i.e. a page can be successfully retrieved from it without error 
    * @param string $url The URL to be checked 
    * @param int $nredirects The number of redirects check so far 
    * @return boolean True if OK, false if the URL cannot be fetched 
    */ 
    static function checkUrl($url, $nredirects = 0) { 
     // First, see if the URL is sensible 
     if (filter_var($url, FILTER_VALIDATE_URL) === false) { 
      self::$lasterror = sprintf('URL "%s" did not validate', $url); 
      return false; 
     } 
     // Now try to fetch it 
     $headers = @get_headers($url); 
     if ($headers == false) { 
      $error = error_get_last(); 
      self::$lasterror = sprintf('URL "%s" could not be read: %s', $url, $error['message']); 
      return false; 
     } 
     $status = $headers[0]; 
     $rbits = explode(' ', $status); 
     if (count($rbits) < 2) { 
      self::$lasterror = sprintf('Cannot parse status "%s" from URL "%s"', $status, $url); 
      return false; 
     } 
     if (in_array($rbits[1], array(301, 302, 304, 307, 308))) { 
      // This URL has been redirected. Follow the redirection chain 
      foreach ($headers as $header) { 
       if (cLib::startsWith($header, 'Location:')) { 
        if (++$nredirects > 10) { 
         self::$lasterror = sprintf('URL "%s" was redirected over 10 times: abandoned check', $url); 
         return false; 
        } 
        return self::checkUrl(trim(substr($header, strlen('Location:'))), $nredirects); 
       } 
      } 
      self::$lasterror = sprintf('URL "%s" was redirected but location could not be identified', $url); 
      return false; 
     } 
     if ($rbits[1] != 200) { 
      self::$lasterror = sprintf('URL "%s" returned status "%s"', $url, $status); 
      return false; 
     } 
     return true; 
    } 
} 

Với lời xin lỗi đến @FranciscoLuz - nếu bạn đang mong lỗi dựa trên người dùng nhập vào, các "@ và error_get_last" phương pháp dường như hoàn toàn hợp lý với tôi - Tôi không thấy có bất cứ điều gì đúng đắn hơn về việc sử dụng set_error_handler .

BTW, không chắc tôi có nên thực hiện việc này dưới dạng chỉnh sửa cho câu trả lời của @ Gordon thay vì trả lời riêng không. Ai đó có thể tư vấn?

0
public function isLink($url) 
{ 
    $result = false; 
    if (!filter_var($url, FILTER_VALIDATE_URL) === false) { 
     $getHeaders = get_headers($url); 
     $result = strpos($getHeaders[0], '200') !== false; 
    } 
    return $result; 
} 
Các vấn đề liên quan