get_headers

(PHP 5)

get_headers — Возвращает заголовки из ответа сервера на HTTP-запрос

Описание

array get_headers ( string $url [, int $format ] )

get_headers() возвращает массив с заголовками из ответа сервера на HTTP-запрос.

Список параметров

url

Целевой URL.

format

Если необязательный параметр format установлен в 1, get_headers() разберет ответ сервера и установит ключи для возвращаемого массива.

Возвращаемые значения

Возвращает список или ассоциативный массив с заголовками ответа при нормальном завершении и FALSE, если возникла ошибка.

Список изменений

Версия Описание
5.1.3 Эта функция теперь использует stream context по-умолчанию, который может быть установлен или изменен при помощи функции stream_context_get_default().

Примеры

Пример #1 Пример использования get_headers()

<?php
$url 
'http://www.example.com';

print_r(get_headers($url));

print_r(get_headers($url1));
?>

Результатом выполнения данного примера будет что-то подобное:

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

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
)

Коментарии

aeontech, this the below change adds support for SSL connections. Thanks for the code!

        if (isset($url_info['scheme']) && $url_info['scheme'] == 'https') {
            $port = 443;
            $fp=fsockopen('ssl://'.$url_info['host'], $port, $errno, $errstr, 30);
        } else {
           $port = isset($url_info['port']) ? $url_info['port'] : 80;
            $fp=fsockopen($url_info['host'], $port, $errno, $errstr, 30);
        }
2005-07-27 08:01:07
http://php5.kiev.ua/manual/ru/function.get-headers.html
The replacement updated get_headers function by aeontech at gmail dot com improperly formats dates when $format = 1.

Replace:
<?
else {
$headers[strtolower($h2[0])] = trim($h2[1]);
}
?>

With:
<?
else {   
$foo implode':'$h2 );
$foo preg_replace'/[a-zA-Z- ]*: /'''$foo );
$headers[strtolower($h2[0])] = trim$foo );
}
2005-07-27 19:10:38
http://php5.kiev.ua/manual/ru/function.get-headers.html
hey, i came across this afew weeks ago and used the function in an app for recording info about domains that my company owns, and found that the status this returns was wrong most of the time (400 bad request or void for sites that were clearly online). then looking into it i noticed the problem was that it wasn't able to get the correct info about sites with redirections. but thats not the full problem because everything on my server was returning the wrong status too. i searched around on php.net for other info and found that fsockopen's example worked better and only needed some tweeking.

heres the function i put together from it and a small change.

<?php
if(!function_exists('get_headers')) {
   function 
get_headers($url,$format=0,$httpn=0){
   
$fp fsockopen($url80$errno$errstr30);
    if (
$fp) {
       
$out "GET / HTTP/1.1\r\n";
       
$out .= "Host: $url\r\n";
       
$out .= "Connection: Close\r\n\r\n";
       
fwrite($fp$out);
       while (!
feof($fp)) {
           
$var.=fgets($fp1280);
       }

   
$var=explode("<",$var);
   
$var=$var[0];
   
$var=explode("\n",$var);
   
fclose($fp);
    return 
$var;
    }
    }
}
?>

this returns an array of the header (only problem being that if the site doesn't have correct html it'll pull in some content too).

hope this'll help someone else.
2005-09-14 15:52:41
http://php5.kiev.ua/manual/ru/function.get-headers.html
Автор:
I've noticed it.
Some Server will simply return the false reply header if you sent 'HEAD' request instead of 'GET'. The 'GET' request header always receiving the most actual HTTP header instead of 'HEAD' request header. But If you don't mind for a fast but risky method then 'HEAD' request is better for you.

btw ... this is get header with additional information such as User, Pass & Refferer. ... 
<?php
   
function get_headers_x($url,$format=0$user=''$pass=''$referer='') {
        if (!empty(
$user)) {
           
$authentification base64_encode($user.':'.$pass);
           
$authline "Authorization: Basic $authentification\r\n";
        }

        if (!empty(
$referer)) {
           
$refererline "Referer: $referer\r\n";
        }

       
$url_info=parse_url($url);
       
$port = isset($url_info['port']) ? $url_info['port'] : 80;
       
$fp=fsockopen($url_info['host'], $port$errno$errstr30);
        if(
$fp) {
           
$head "GET ".@$url_info['path']."?".@$url_info['query']." HTTP/1.0\r\n";
            if (!empty(
$url_info['port'])) {
               
$head .= "Host: ".@$url_info['host'].":".$url_info['port']."\r\n";
            } else {
               
$head .= "Host: ".@$url_info['host']."\r\n";
            }
           
$head .= "Connection: Close\r\n";
           
$head .= "Accept: */*\r\n";
           
$head .= $refererline;
           
$head .= $authline;
           
$head .= "\r\n";

           
fputs($fp$head);       
            while(!
feof($fp) or ($eoheader==true)) {
                if(
$header=fgets($fp1024)) {
                    if (
$header == "\r\n") {
                       
$eoheader true;
                        break;
                    } else {
                       
$header trim($header);
                    }

                    if(
$format == 1) {
                   
$key array_shift(explode(':',$header));
                        if(
$key == $header) {
                           
$headers[] = $header;
                        } else {
                           
$headers[$key]=substr($header,strlen($key)+2);
                        }
                    unset(
$key);
                    } else {
                       
$headers[] = $header;
                    }
                } 
            }
            return 
$headers;

        } else {
            return 
false;
        }
    }
?>

Regards.
Donovan
2006-11-13 02:29:21
http://php5.kiev.ua/manual/ru/function.get-headers.html
I tried to replicate the native behavior as much as possible for systems that don't have the get_headers() function. Here it is:
<?php
if (!function_exists('get_headers')) {
function 
get_headers($Url$Format0$Depth0) {
    if (
$Depth 5) return;
   
$Parts parse_url($Url);
    if (!
array_key_exists('path'$Parts))   $Parts['path'] = '/';
    if (!
array_key_exists('port'$Parts))   $Parts['port'] = 80;
    if (!
array_key_exists('scheme'$Parts)) $Parts['scheme'] = 'http';

   
$Return = array();
   
$fp fsockopen($Parts['host'], $Parts['port'], $errno$errstr30);
    if (
$fp) {
       
$Out 'GET '.$Parts['path'].(isset($Parts['query']) ? '?'.@$Parts['query'] : '')." HTTP/1.1\r\n".
               
'Host: '.$Parts['host'].($Parts['port'] != 80 ':'.$Parts['port'] : '')."\r\n".
               
'Connection: Close'."\r\n";
       
fwrite($fp$Out."\r\n");
       
$Redirect false$RedirectUrl '';
        while (!
feof($fp) && $InLine fgets($fp1280)) {
            if (
$InLine == "\r\n") break;
           
$InLine rtrim($InLine);

            list(
$Key$Value) = explode(': '$InLine2);
            if (
$Key == $InLine) {
                if (
$Format == 1)
                       
$Return[$Depth] = $InLine;
                else   
$Return[] = $InLine;

                if (
strpos($InLine'Moved') > 0$Redirect true;
            } else {
                if (
$Key == 'Location'$RedirectUrl $Value;
                if (
$Format == 1)
                       
$Return[$Key] = $Value;
                else   
$Return[] = $Key.': '.$Value;
            }
        }
       
fclose($fp);
        if (
$Redirect && !empty($RedirectUrl)) {
           
$NewParts parse_url($RedirectUrl);
            if (!
array_key_exists('host'$NewParts))   $RedirectUrl $Parts['host'].$RedirectUrl;
            if (!
array_key_exists('scheme'$NewParts)) $RedirectUrl $Parts['scheme'].'://'.$RedirectUrl;
           
$RedirectHeaders get_headers($RedirectUrl$Format$Depth+1);
            if (
$RedirectHeaders$Return array_merge_recursive($Return$RedirectHeaders);
        }
        return 
$Return;
    }
    return 
false;
}}
?>
The function will handle up to five redirects.
Enjoy!
2008-06-05 16:59:32
http://php5.kiev.ua/manual/ru/function.get-headers.html
Should be the same than the original get_headers():

<?php
if (!function_exists('get_headers')) {
function 
get_headers($url$format=0) {
   
$headers = array();
   
$url parse_url($url);
   
$host = isset($url['host']) ? $url['host'] : '';
   
$port = isset($url['port']) ? $url['port'] : 80;
   
$path = (isset($url['path']) ? $url['path'] : '/') . (isset($url['query']) ? '?' $url['query'] : '');
   
$fp fsockopen($host$port$errno$errstr3);
    if (
$fp)
    {
       
$hdr "GET $path HTTP/1.1\r\n";
       
$hdr .= "Host: $host \r\n";
       
$hdr .= "Connection: Close\r\n\r\n";
       
fwrite($fp$hdr);
        while (!
feof($fp) && $line trim(fgets($fp1024)))
        {
            if (
$line == "\r\n") break;
            list(
$key$val) = explode(': '$line2);
            if (
$format)
                if (
$val$headers[$key] = $val;
                else 
$headers[] = $key;
            else 
$headers[] = $line;
        }
       
fclose($fp);
        return 
$headers;
    }
    return 
false;
}
}
?>
2008-06-21 08:04:49
http://php5.kiev.ua/manual/ru/function.get-headers.html
<?php
/**
 * Fetches all the real headers sent by the server in response to a HTTP request without redirects
 *
 * @link      http://php.net/function.get_headers
 * @link      http://bugs.php.net/bug.php?id=50719 
 */

function get_real_headers($url,$format=0,$follow_redirect=0) {
  if (!
$follow_redirect) {
   
//set new default options
   
$opts = array('http' =>
        array(
'max_redirects'=>1,'ignore_errors'=>1)
    );
   
stream_context_get_default($opts);
  }
 
//get headers
   
$headers=get_headers($url,$format);
   
//restore default options
 
if (isset($opts)) {
   
$opts = array('http' =>
        array(
'max_redirects'=>20,'ignore_errors'=>0)
    );
   
stream_context_get_default($opts);
  }
 
//return
   
return $headers;
}
?>
2010-01-28 12:20:25
http://php5.kiev.ua/manual/ru/function.get-headers.html
Seems like there are some people who are looking for only the 3-digit HTTP response code  - here is a quick and nasty solution:

<?php
function get_http_response_code($theURL) {
   
$headers get_headers($theURL);
    return 
substr($headers[0], 93);
}
?>

How easy is that? Echo the function containing the URL you want to check the response code for, and voilà. Custom redirects, alternative for blocked is_file() or flie_exists() functions (like I seem to have on my servers) hence the cheap workaround. But hey - it works!

Pudding
2010-05-02 20:28:29
http://php5.kiev.ua/manual/ru/function.get-headers.html
Автор:
Note that get_headers **WILL follow redirections** (HTTP redirections). New headers will be appended to the array if $format=0. If $format=1 each redundant header will be an array of multiple values, one for each redirection.

For example:

<?php
$url 
'http://google.com';
var_dump(get_headers($url,0));
/*array(18) {
  [0]=>  string(30) "HTTP/1.0 301 Moved Permanently"
  [1]=>  string(32) "Location: http://www.google.com/"
  [2]=>  string(38) "Content-Type: text/html; charset=UTF-8"
  [3]=>  string(35) "Date: Sun, 26 Sep 2010 00:59:50 GMT"
  [4]=>  string(38) "Expires: Tue, 26 Oct 2010 00:59:50 GMT"
  [5]=>  string(38) "Cache-Control: public, max-age=2592000"
....
  string(15) "HTTP/1.0 200 OK"
  [10]=>  string(35) "Date: Sun, 26 Sep 2010 00:59:51 GMT"
  [11]=>  string(11) "Expires: -1"
  [12]=>  string(33) "Cache-Control: private, max-age=0"
.....
}*/

/*===========================*/

var_dump(get_headers($url,1));
/*array(11) {
  [0]=>
  string(30) "HTTP/1.0 301 Moved Permanently"
  ["Location"]=>  string(22) "http://www.google.com/"
  ["Content-Type"]=>  array(2) {
    [0]=>    string(24) "text/html; charset=UTF-8"
    [1]=>    string(29) "text/html; charset=ISO-8859-1"
  }
  ["Date"]=>  array(2) {
    [0]=>    string(29) "Sun, 26 Sep 2010 01:03:39 GMT"
    [1]=>    string(29) "Sun, 26 Sep 2010 01:03:39 GMT"
  }
  ["Expires"]=>  array(2) {
    [0]=>    string(29) "Tue, 26 Oct 2010 01:03:39 GMT"
    [1]=>    string(2) "-1"
  }
  ["Cache-Control"]=>  array(2) {
    [0]=>    string(23) "public, max-age=2592000"
    [1]=>    string(18) "private, max-age=0"
  }
.....
}*/
?>
2010-09-25 21:13:47
http://php5.kiev.ua/manual/ru/function.get-headers.html
Автор:
It should be noted that rather than returning "false" on failure, this function (and others) return a big phat WARNING that will halt your script in its tracks if you do not have error reporting /warning turned off.

Thats just insane!  Any function that does something like fetch a URL should simply return false, without a warning, if the URL fails for whatever reason other than it is badly formatted.
2012-02-15 21:06:56
http://php5.kiev.ua/manual/ru/function.get-headers.html
Автор:
I know you're not supposed to reference other notes, but sincere props to Nick at Innovaweb's comment, for which I base this addition to his idea:

If you use that function, it will return a string, which is great if you are checking for only files that return 404, or 200, or whatnot.  If you cast the string value to an integer, you can perform mathematical comparison on it. 

For example:

<?php
function get_http_response_code($theURL) {
   
$headers get_headers($theURL);
    return 
substr($headers[0], 93);
}

if(
intval(get_http_response_code('filename.jpg')) < 400){
// File exists, huzzah!
}
?>

Rule of thumb is if the response is less than 400, then the file's there, even if it doesn't return 200.
2013-07-09 17:47:55
http://php5.kiev.ua/manual/ru/function.get-headers.html
Автор:
If you don't want to display Warning when get_headers() function fails, you can simply add at-sign (@) before it.

<?php

// in failure, Warning will be hidden and false returned
$withoutWarning = @get_headers("http://www.some-domain.com");

// in  failure, Warning displays and false will be returned, too
$withWarning get_headers("http://www.some-domain.com");

// bool(false)
var_dump($withoutWarning);
// bool(false)
var_dump($withWarning);
?>
2013-11-24 11:55:39
http://php5.kiev.ua/manual/ru/function.get-headers.html
@Jim Greene:

if the URL does not exist, it returns incomplete headers, making the substring default to rubbish.

The integer value of rubbish is always 0. So your lower than 400 does not always means it exists!
2015-02-23 11:20:33
http://php5.kiev.ua/manual/ru/function.get-headers.html
Note that get_headers should not be used against a URL that was gathered via user input. The timeout option in the stream context only affects the idle time between data in the stream. It does not affect connection time or the overall time of the request. 

(Unfortunately, this is not mentioned in the docs for the timeout option, but has been discussed in a number of code discussions elsewhere, and I have done my own tests to confirm the conclusions of those discussions.)

Thus it is very easy for a user to give you a URL that acts like a Slowloris attack - feeding your get_headers function 1 header only often enough to avoid the stream timeout.

If you are publishing your code, even default_socket_timeout cannot be relied on to remedy this, because it is broken for the HTTPS protocol on many but the more recent versions of PHP: https://bugs.php.net/bug.php?id=41631

With get_headers accepting user input, it can be very easy for an attacker to make all of your PHP child processes become busy.

Instead, use cURL functions to get headers for a URL provided by the user and parse those headers manually, as CURLOPT_TIMEOUT applies to the entire request.
2015-04-29 17:41:26
http://php5.kiev.ua/manual/ru/function.get-headers.html
To check URL validity, this has been working nicely for me:

function url_valid(&$url) {
  $file_headers = @get_headers($url);
  if ($file_headers === false) return false; // when server not found
  foreach($file_headers as $header) { // parse all headers:
    // corrects $url when 301/302 redirect(s) lead(s) to 200:
    if(preg_match("/^Location: (http.+)$/",$header,$m)) $url=$m[1]; 
    // grabs the last $header $code, in case of redirect(s):
    if(preg_match("/^HTTP.+\s(\d\d\d)\s/",$header,$m)) $code=$m[1]; 
  } // End foreach...
  if($code==200) return true; // $code 200 == all OK
  else return false; // All else has failed, so this must be a bad link
} // End function url_exists
2016-06-22 02:30:46
http://php5.kiev.ua/manual/ru/function.get-headers.html
If the URL redirected and the new target is also redirected, we got the Locations in array. Also we got the HTTP codes in a number indexed values. 

Here a PART of the header (not all), how it is look like with this redirection chain ( the id=4 is the landing page):
/test.php?id=1 -> /test.php?id=2 -> /test.php?id=3 -> /test.php?id=4

array 
(
    [0] => HTTP/1.1 302 Moved Temporarily

    [Location] => Array
        (
            [0] => /test.php?id=2
            [1] => /test.php?id=3
            [2] => /test.php?id=4
        )

    [1] => HTTP/1.1 302 Moved Temporarily
    [2] => HTTP/1.1 302 Moved Temporarily
    [3] => HTTP/1.1 200 OK
)

In a typical situation we need only the landing page information, so here is a small code to get it:

$result = array();
$header = get_headers($url, 1);
foreach ($header as $key=>$value) {
    if (is_array($value)) {
        $value = end($value);
    }
    $result[$key] = $value;
}
2016-10-22 17:26:13
http://php5.kiev.ua/manual/ru/function.get-headers.html
Автор:
How to check if a url points to a valid video

<?php 
function isVideo($url){
   
$url get_headers($url,1);
    if(
is_array($url['Content-Type'])){ //In some responses Content-type is an array
       
$video strpos($url['Content-Type'][1],'video');
    }else{
       
$video strpos($url['Content-Type'],'video');
    }
    if(
$video !== false)
        return 
true;
   
    return 
false;
}

?>
2018-10-15 20:17:40
http://php5.kiev.ua/manual/ru/function.get-headers.html

    Поддержать сайт на родительском проекте КГБ