- Может ли PHP использовать cURL для получения заголовка и тела ответа на запрос?
- Ответ 1
- Ответ 2
- Как получить заголовки HTTP с сервера через cURL
- Комментарии (0):
- Как просмотреть заголовки HTTP
- Что такое заголовки HTTP?
- Как просмотреть заголовки HTTP в веб-браузере
- Как отображать заголовки HTTP в cURL
- Заголовки HTTP в Burp Suite
- get_headers
- Описание
- Список параметров
- Возвращаемые значения
- Список изменений
- Примеры
- См. также
- Примечания, добавленные пользователем 28 примечаний
Может ли PHP использовать cURL для получения заголовка и тела ответа на запрос?
Есть ли способ получить заголовок и тело запроса cURL с помощью PHP? Я обнаружил, что эта опция:
curl_setopt($ch, CURLOPT_HEADER, true);
возвращает тело плюс заголовок, но затем мне нужно проанализировать его, чтобы получить тело . Есть ли лучший (и более безопасный) способ получить оба?
Обратите внимание, что под «единым запросом» я подразумеваю не отправлять запрос HEAD перед GET/POST.
Ответ 1
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
// Затем после вызова curl_exec:
$header_size = curl_getinfo($ ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
Предупреждение. Этот код может быть ненадежным при использовании с прокси-серверами или при обработке определенных типов перенаправлений.
Ответ 2
Предыдущий ответ не совсем правильный.
Разделение на \r \n\r\n\n ненадежно, если CURLOPT_FOLLOWLOCATION включен или если сервер отвечает кодом 100.
Не все серверы, соответствующие стандартам, передают только \n для разрывов строк.
Определение размеров заголовков через CURLINFO_HEADER_SIZE также не всегда надежно, особенно при использовании прокси или в некоторых подобных случаях через ering.
Самый правильный метод — использовать CURLOPT_HEADERFUNCTION.
Вот очень чистый метод для выполнения этой функции с помощью PHP-замыканий. Он также преобразует все заголовки в нижний регистр для согласованной работы на разных HTTP-серверах и версиях.
В этой версии будут сохранены повторяющиеся заголовки.
Этот код соответствует RFC822 и RFC2616, не предлагайте модификациям использовать функции mb_string, это неправильно !
curl_setopt($channel, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// curl вызывает эту функцию для каждого полученного заголовка
Источник
Как получить заголовки HTTP с сервера через cURL
В этой статье вы и я будет продолжено в нашем учебном пособии по модулю cURL и на этот раз вы узнаете как найти заголовки HTTP сервера с помощью cURL .
Чтобы получить заголовки HTTP с сервера через cURL запустите следующий код:
Как и прежде, curl_init() инициализирует сеанс cURL . Затем приступаем к настройке следующих параметров:
- CURLOPT_URL=»http://myrusakov.ru» . Это URL-адрес веб-сайта, имя которого мы хотим получить.
- CURLOPT_RETURNTRANSFER = true . С этой опцией мы требуем, чтобы ответ возвращался, а не отправлялся непосредственно в браузер.
- CURLOPT_NOBODY = true . Здесь мы требуем, чтобы содержимое самого документа не включалось в ответ.
- CURLOPT_HEADER = true . Это самый важный вариант, не так ли? содержит ваши заголовки HTTP .
в ответе от сервера
Затем мы делаем наш запрос cURL с помощью функции curl_exec() и получаем ответ, который записываем в переменную $out . Затем мы транслируем его и закрываем соединение.
Как можно использовать эту информацию? Самый простой пример — проверить: доступна страница или нет . Поэтому, если код состояния 404 , страница недоступна. Вот можно создать такой полезный сервис, где люди смогут проверить, работает сайт или нет. Это может быть очень полезно, потому что иногда ваш компьютер блокирует доступ к некоторым сайтам, а также некоторые сайты могут блокировать доступ к вам по IP-адресу . Но благодаря такому сервису будет показано реальное положение вещей на сервере. Так что смело творите и удачи!
Копирование материалов разрешено только с указанием автора (Михаил Русаков) и прямой индексируемой ссылкой на сайт (http://myrusakov.ru)!
Добавь меня в друзья ВКонтакте : http://vk.com/myrusakov.
Если вы хотите оценить меня и мою работу, пишите в мою группу: http://vk.com/rusakovmy.
Если вы не хотите пропускать новые материалы на сайте,
тогда вы можете подписаться на обновления : Подписаться на обновления
Если у вас есть какие-либо вопросы или вы хотите прокомментировать эту статью, вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью своим друзьям:
Если вам понравилась страница, поставьте ссылку на нее (на ваш сайт, форум, в контакт):
Это выглядит так:
Комментарии (0):
Вы должны войти, чтобы добавить Комментарии.
Если вы не зарегистрированы на сайте, сначала зарегистрируйтесь.
Copyright © 2010-2022 Михаил Русаков. Все права защищены.
Источник
Как просмотреть заголовки HTTP
Что такое заголовки HTTP?
Протокол HTTP используется при открытии страниц и загрузке файлов из Интернета. Протокол HTTP работает по принципу «запрос-ответ»: от клиента приходит запрос, а сервер отправляет ответ. Каждый запрос и каждый ответ состоит из элементов:
- Строка вывода
- Заголовок
- Тело сообщения
Тело сообщения — это то, для чего предназначен запрос: веб-страница или файл.
заголовки — это метаинформация, которую мы обычно не видим.< 4>
Заголовки запросов могут содержать такие данные, как:
- предпочитаемые языки
- характеристика запрашивающей программы
- содержимое файлов cookie
- информация о сервере: для какого хоста запрос и т.д.
Заголовки ответа могут содержать такие данные, как:
- Кодировка отправляемого текста
- тип отправляемого контента (изображение, текст, файл и т. д.)
- данные программного обеспечения веб-сервера
- данные кэша: программное обеспечение, используемое для кэширование, возраст отправленных данных и т. д.
Эта статья покажет вам, как просматривать заголовки HTTP.
Как просмотреть заголовки HTTP в веб-браузере
Это самый простой метод, доступный в любой операционной системе.
Нажмите F12 в веб-браузере, чтобы открыть интересующую вас страницу. Перейдите на вкладку Сеть и выберите интересующее вас подключение.
Сначала идет Заголовок ответа , а затем Заголовок запроса , хотя, конечно, сначала это отправляет запрос и его заголовки, и только потом приходит ответ.
Это удобный метод, и вам не нужно беспокоиться о HTTPS; поскольку веб-браузер является конечным пунктом назначения, он может отображать уже расшифрованные данные.
Как отображать заголовки HTTP в cURL
Для cURL есть опции -I, -v и -i, утилиты, которые делают это, будут отображать заголовки HTTP.
Разница в том, что опция -I означает использование метода HEAD , т.е. фактически не будет отправлено ничего, кроме HTTP-заголовков. А опция -v делает вывод более подробным, что приводит к включению заголовков. Но если вы отправляете запрос по HTTPS, то с опцией -v также будут отображаться данные, относящиеся к рукопожатию TLS; они не связаны с HTTP. заголовки Следует также отметить, что параметр -I отображает только заголовки ответов, а параметр -v показывает заголовки запросов и заголовки ответов. Параметр
-i также показывает только заголовки ответа, а не рукопожатие TLS, но показывает все тело ответа.
Пример метода HEAD:
Здесь » HTTP/1.1 200 OK » — это строка состояния, а все остальное — это поля заголовка HTTP.
Пример устного вывода:
Заголовок, отправленный на веб-сервер begin > , в то время как строки, полученные от веб-сервера, начинаются с
Преимущество Wireshark в том, что вы можете использовать мощную систему фильтрации и гибкую систему поиска полей заголовков в дополнение для отображения заголовков HTTP. Подробнее см. в справочной статье Wireshark Filters.
Заголовки HTTP в Burp Suite
Burp Suite включает прокси-сервер специально для просмотра заголовков. Кроме того, в программе есть функции для редактирования заголовков и другого контента на лету. Но Burp Suite — это профессиональная программа, которой нужно учиться.
Burp Suite может обрабатывать HTTPS-запросы, но требует настройки SSL-сертификатов в веб-браузере.
См. также обширную статью «Протокол HTTP», которая содержит подробное, но понятное описание протокола.
См. также соответствующую статью: Отображение данных POST с помощью cURL.
Source
get_headers
(PHP 5, PHP 7 PHP 8)
get_headers — возвращает все заголовки из ответа сервера на HTTP-запрос
Описание
get_headers() возвращает массив заголовков из ответа сервера на HTTP-запрос.
Список параметров
Если необязательный ассоциативный параметр имеет ненулевое значение, get_headers() анализирует ответ сервера и устанавливает ключи для возвращаемого поля.
Действительный контекст ресурса, созданный с помощью функции stream _context_create() или null для использования контекста ресурса по умолчанию.
Возвращаемые значения
Возвращает ассоциативный или индексированный массив заголовков ответа или false в случае ошибки.
Список изменений
Версия | Описание |
---|---|
8.0 . 0 | Тип ассоциативного параметра изменен с целочисленного (int) на логический (bool). |
7.1.0 | Добавлен параметр контекста. |
Примеры
Пример #1 get_headers() пример
print_r (get_headers ($url));
print_r (get_headers ($url, true));
?>
Результатом этого примера будет что-то вроде этого:
Пример #2 пример запроса HEAD в функции get_headers()
См. также
Примечания, добавленные пользователем 28 примечаний
Кажется, что некоторые люди ищут только трехзначный код ответа HTTP. и уродливое решение:
function get_http_response_code ( $theURL ) <
$headers = get_headers ( $theURL );
вернуть подстроку ($headers [ 0 ], 9 , 3 );
>
?>
Насколько это просто? Отправьте функцию, содержащую URL-адрес, для которого вы хотите проверить код ответа, и все готово. Пользовательские перенаправления, резервные функции is_file() или fly_exists() заблокированы (кажется, на моих серверах), поэтому дешевое решение. Но эй, это работает!
Обновленная функция замены get_headers от aeontech в gmail dot com неправильно форматирует данные, когда $format = 1.
Если URL-адрес перенаправляется, и новая цель также перенаправляется, у нас есть местоположение массива. Мы также получили HTTP-коды для ряда проиндексированных значений.
Вот ЧАСТЬ заголовков (не все), как это выглядит с этой строкой перенаправления (это целевая страница):
/test. php?id=1 -> /test.php?id=2 -> /test.php?id=3 -> /test.php?id=4
массив
(
[0] => HTTP/1.1 302 Временно перемещен
[Расположение] => Массив
(
[0] => /test.php?id=2
[1] => /test.php?id=3
[2] => /test.php?id =4
)
[1] => HTTP/1.1 302 временно перемещено
[2] => HTTP/1.1 302 временно перемещено
[3] => HTTP/ 1.1 200 OK
)
В типичной ситуации нам нужна только информация о целевой странице, поэтому вот небольшой код для ее получения:
$result = array() ;
$header = get_headers($url, 1);
foreach ($header as $key=>$value) <
if (is_array($value)) <
$значение = конец($значение);
>
$результат[$ключ] = $значение;
>
Как проверить, ссылается ли URL на действительное видео
function isVideo ($url) <
$url = get_headers ($url, 1);
if( is_array ($url [ ‘Content-Type’ ])) < // В некоторых ответах тип контента — field
$video = strpos ( $url [ ‘Content-Type’ ][ 1 ], ‘video’ );
>еще <
$video = strpos ($url [‘Content-Type’], ‘video’);
>
if ($video!== false)
вернуть true;
Я попытался максимально воспроизвести нативное поведение для систем, в которых нет функции get_headers(). Вот оно:
if (! function_exists (‘get_headers’)) <
функция get_headers ($Url, $Format = 0, $Depth = 0) <
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 (‘schema’, $Parts)) $Parts [‘schema’] = ‘http’;
$Return = array();
$fp = fsockopen ($Parts [‘хост’], $Parts [‘порт’], $errno, $errstr, 30);
если ($fp) <
$Вывод = ‘ПОЛУЧИТЬ’. $Parts [ ‘путь’ ].(isset( $Parts [ ‘запрос’ ]) ? ‘?’ .@ $Parts [ ‘запрос’ ] : » ). «HTTP/1.1\r\n» .
‘Хост:’ . $Parts [ ‘хост’ ].( $Parts [ ‘порт’ ] != 80 ? ‘:’ . $Parts [ ‘порт’ ] : » ). «\р\п» .
«Соединение: закрыть» . «\г\п»;
fwrite ($fp, $Out. «\r\n»);
$Redirection = false; $RedirectUrl = »;
while (! feof ($fp) && $InLine = fgets ($fp , 1280 )) <
if ( $InLine == «\r\n» ) break;
$InLine = rtrim ( $InLine );
seznam($Key, $Value) = взорвать(‘:’, $InLine, 2);
если ( $Heslo == $OnLine ) <
if ($Format == 1)
$Return [$Hloubka] = $InLine;
иначе $Return [] = $InLine ;
if (strpos ($InLine, ‘Moved’)> 0) $Redirect = true;
> джинак <
if ( $Key == ‘Umístění’ ) $RedirectUrl = $Value ;
if ($Formát == 1)
$Return [$Key] = $Hodnota;
jinak $Return [] = $Key . ‘:’ . $ Годнота ;
>
>
fclose ($fp);
if ( $Redirect && !empty( $RedirectUrl )) <
$NewParts = parse_url ( $RedirectUrl );
if (! array_key_exists(‘хост’, $NewParts)) $RedirectUrl = $Parts [‘хоститель’]. $Редиректурл;
if (! array_key_exists(‘schema’, $NewParts)) $RedirectUrl = $Parts[‘schéma’]. ‘://’. $Редиректурл;
$RedirectHeaders = get_headers ($RedirectUrl, $Format, $Hloubka + 1);
if ($RedirectHeaders) $Return = array_merge_recursive ($Return, $RedirectHeaders);
>
вернуть $Return ;
>
vrací false ;
>>
?>
Funkce zvládne až pět přesměrování.
Užijte si to!
Vím, že se v komentáři na Innovawebu nemáte odvolávat na jiné poznámky, ale na srdečnou podporu Nicka, takže tento dodatek zakládám na jeho nápadu:
Если вы используете эту функцию, она вернет строку, что отлично, если вы ищете только файлы, которые возвращают 404, 200 или что-то еще. Если вы преобразуете строковое значение в целое число, вы можете выполнить с ним математическое сравнение.
функция get_http_response_code ( $theURL ) <
$headers = get_headers ( $theURL );
вернуть подстроку ($headers [0], 9, 3);
>
if( intval ( get_http_response_code ( ‘имя_файла.jpg’ )) 400 ) <
// Файл существует, ура!
>
?>
Как правило, если ответ меньше 400, то файл существует, даже если он не возвращает 200.
если URL не существует, он возвращает неполные заголовки, что означает, что подстрока является ерундой по умолчанию.
Значение целого числа мусора всегда равно 0. Таким образом, его значение меньше 400 не всегда означает, что оно существует!
Обратите внимание, что get_headers * *БУДЕТ ПОСЛЕДСТВОВАТЬ за перенаправлением** (перенаправление HTTP). Если $format=0, в поле будут добавлены новые заголовки. Если $format=1, каждый избыточный заголовок будет массивом из нескольких значений, по одному для каждого перенаправления.
= ‘http://google.com’;
var_dump(get_headers($url, 0));
/*массив(18) <
[0]=> string(30) «HTTP/1.0 301 перемещен навсегда»
[1]=> string(32) «Расположение: http://www.google.com/»
[2]=> string(38) «Тип содержимого: text/html; charset=UTF-8»
[3]=> string(35) «Дата: воскресенье, 26 сентября 2010 г., 00:59:50 по Гринвичу»
[4]=> string(38) «Срок действия истекает: Вт, 26 октября 2010 г., 00:59:50 по Гринвичу»
[5]=> string(38) «Управление кешем: public, max-age=2592000»
.
string(15) » HTTP /1.0 200 OK»
[10]=> строка (35) «Дата: воскресенье, 26 сентября 2010 г., 00:59:51 по Гринвичу»
[11] => строка (11) «Срок действия истекает: -1»
[12]=> string(33) «Управление кешем: частный, максимальный возраст = 0»
.
>*/
var_dump (get_headers ($url , 1));
/*field(11) <
[0]=>
string(30) «HTTP/1.0 301 перемещен навсегда»
[«Расположение» ]=> ; string(22) «http://www.google.com/»
[«Content-Type»]=> field(2) <
[0]=> string( 24) » текст/html; charset=UTF-8″
[1]=> строка(29) «text/html; charset=ISO-8859-1»
>
[«Дата»]=> field(2) <
[0]=> string(29) «Воскресенье, 26 сентября 2010 г. 01:03:39 GMT»
[1]=> string(29) «Воскресенье, 26 сентября 2010 г. 01:03:39 GMT»
>
[«Expires»]=> ; array (2) <
[0]=>string(29) «Вторник, 26 октября 2010 г., 01:03:39 по Гринвичу»
[1]=>string(2) «-1»
>
[«Проверка кеша»]=>field(2) <
[0]=>string(23) «public, max-age=2592000»
[ 1] => string(18) «private, max-age=0»
>
.
>*/
?>
Если вы не хотите при сбое функции get_headers() для отображения предупреждения можно просто добавить скобку (@) перед ней
// при сбое предупреждение будет скрыто и возвращено false
$noWarning = @get_headers( «http://www.some — domain.com»);
// в случае ошибки Warning и false также отображаются при ошибке
$withWarning = get_headers («http://www.some-domain.com»);
// bool(false)
var_dump ($noWarning);
// bool(false)
var_dump ($withWarning);
?>
Привет, я наткнулся на это несколько недель назад и использовал эту функцию в приложении для регистрации информации о доменах, с которыми у меня есть компания, и обнаружил, что статус, который он возвращал, был неверным большую часть времени (400 плохих запросов или нет запросов для сайтов, которые явно были в сети) .когда я изучил это, я понял, что проблема в том, что я не могу получить правильную информацию о сайтах перенаправления… но это не вся проблема, потому что все на моем сервере также возвращало неправильный статус. Я искал на php. net больше информации и обнаружил, что пример fsockopen работает лучше и требует лишь нескольких настроек.
вот функция, которую я сделал из него, и одно небольшое изменение.
if( function_exists ( ‘get_headers ‘ )) <
функция get_headers ($url, $format = 0, $httpn = 0) <
$fp = fsockopen ($url, 80, $errno, $errstr, 30);
если ($fp) <
$out = «GET / HTTP/1.1\r\n» ;
$out .= «Хост: $url \r\n» ;
$out .= «Соединение: закрыть\r\n\r\n» ;
fwrite ($fp, $out);
while (! feof ($fp)) <
$var .= fgets ( $fp , 1280);
>
$var = взорвать ( » , $var );
$var = $var [ 0 ];
$var = взорвать («\n» , $var ) ;
fclose ( $фп);
вернуть $var ;
>
>
>
?>
это вернет поле заголовка (только проблема в том, что если страница не имеет правильного html, она также загрузит некоторый контент).
Я надеюсь, что это поможет кому-то еще.
Обратите внимание, что get_headers не следует использовать для URL-адресов, которые собираются посредством пользовательского ввода. Параметр тайм-аута в контексте потока влияет только на время простоя между данными в потоке. Это не влияет на время соединения или общее время запроса.
(К сожалению, это не упоминается в документации для параметра тайм-аута, но обсуждалось в различных обсуждениях кода в других местах, и я провел свои собственные тесты, чтобы подтвердить выводы этих обсуждений).
Таким образом, пользователю очень легко дать вам URL-адрес, который действует как атака Slowloris: заполняйте вашу функцию get_headers одним заголовком достаточно часто, чтобы избежать тайм-аута передачи.
Если вы публикуете свой код, вы даже не можете полагаться на default_socket_timeout, чтобы исправить его, потому что он не работает для HTTPS во многих версиях PHP, кроме последней: https://bugs. php.net/ошибка. php?id=41631
Поскольку get_headers принимает пользовательский ввод, злоумышленнику может быть очень легко занять все ваши дочерние процессы PHP.
Чтобы получить заголовки для пользователя, вместо этого используйте функцию cURL, предоставив URL-адрес и проанализировав эти заголовки вручную, поскольку CURLOPT_TIMEOUT применяется ко всему запросу.
Для проверки правильности URL я нашел очень полезным:
function url_valid(& $url) <
$file_headers = @get_headers($url);
if ($file_headers === false) вернуть false; // когда сервер не найден
foreach($file_headers as $header) < // разобрать все заголовки:
// исправить $url, когда перенаправления 301/302 ведут к 200:
if(preg_match(«/^Location: (http.+)$/» , $header,$m ) ) $url=$m[1];
// на всякий случай берем последний тег $header $ из перенаправления(ов):
if(preg_match(«/^HTTP.+\s(\d\d\d)\s/», $ заголовок,$m)) $code=$m[1];
> // Конец foreach.
если ($code==200) вернуть true; // $code 200 == все в порядке
else return false; // Все остальное не удалось, значит, это плохая ссылка
> // End function url_exists
/**
* Получает все фактические заголовки, отправленные сервером в ответ на HTTP-запрос без перенаправления
*
* @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 ) <
если (! $follow_redirect ) <
// установить новые параметры по умолчанию
$opts = array( ‘ http’ =>
array( ‘max_redirects’ => 1 , ‘ignore_errors’ => 1 )
);
stream_context_get_default ($options);
>
//получить заголовки
$headers = get_headers ($url, $format);
//восстановить параметры по умолчанию
если (иссет( $opts )) <
$opts = array( ‘http’ =>
array( ‘max_redirects’ => 20, ‘ignore_errors’ => 0)
);
stream_context_get_default($options);
>
//возврат
return $headers ;
>
?>
Должно быть таким же, как исходный метод get_headers():
if (!function_exists(‘get_headers’)) <
функция get_headers($url, $format = 0) <
$headers = array();
$url = parse_url($url);
$host = isset( $url [‘host’]) ? $url[‘хост’]:»;
$port = isset( $url [‘порт’]) ? $url[‘порт’]: 80;
$route = (isset( $url[‘route’]) ? $url[‘route’]: ‘/’). (isset($url[‘запрос’])? ‘?’.$url[‘запрос’]: »);
$fp = fsockopen($host, $port, $errno, $errstr, 3);
если ($ fp )
< ;
$hdr = «GET $HTTP_ROUTE/1.1\r\n» ;
$hdr .= «Хост: $host\r\n» ;
$hdr .= «Соединение: Закрыть\r\n\r\n» ;
fwrite($fp, $hdr);
while (! feof($fp) && $line = trim(fgets($fp, 1024)))
<
if ( $line == «\r\n» ) break;
list($key, $value) = decompose(‘:’, $row, 2);
if ($format)
if ($val) $headers[$key] = $val;
else $headers [] = $key ;
else $headers [] = $line ;
>
fclose($fp);
вернуть $headers;
>
вернуть ложь;
>
>
?>
Я это заметил.
Некоторые серверы просто возвращают заголовок ответа false, если они отправили запрос «HEAD» вместо «GET». Заголовок запроса «GET» всегда получает более актуальный заголовок HTTP вместо заголовка запроса «HEAD». Но если вы не возражаете против быстрого, но рискованного подхода, вам лучше подойдет запрос HEAD.
if (!empty( $referer )) <
$refererline = «Referer: $referer \r\n» ;
>
$url_info = parse_url ($url);
$port = isset( $url_info [‘порт’]) ? $url_info [‘порт’]: 80;
$fp = fsockopen ($url_info [‘хост’], $port, $errno, $errstr, 30);
если( $fp ) <
$head = «GET» .@ $url_info [‘путь’]. «?» .@ $url_info [‘запрос’]. » HTTP/1.0\r\n» ;
if (!empty( $url_info [ ‘port’ ])) <
$head .= «Хост: » .@ $url_info [‘хост’]. «:». $url_info [‘порт’]. «\г\п»;
> иначе <
$head .= «Хост: » .@ $url_info [‘хост’]. «\г\п»;
>
$head .= «Соединение: Закрыть\r\n» ;
$head .= «ОК: */*\r\n» ;
$head .= $reference line;
$head .= $authline ;
$head .= «\r\n» ;
fputs ($fp, $head);
while(! feof ($fp) или ( $eoheader == true )) <
if( $header = fgets ( $fp , 1024 )) <
if ($header == » \r\n» ) <
$eoheader = true ;
перерыв;
> иначе <
$header = обрезка ( $header );
>
if( $format == 1 ) <
$key = array_shift (взорвать (‘:’, $header));
if( $key == $header ) <
$headers [] = $header ;
> иначе <
$headers [$key]= substr($header, strlen ($key)+ 2);
>
отключено ( $key );
> иначе <
$headers [] = $header ;
>
>
>
вернуть $headers;
aeontech, это изменение ниже добавляет поддержку соединений SSL. Спасибо за код!
if (isset($url_info[‘schema’]) && $url_info[‘schema’] == ‘https’) <
$port = 443;
$fp=fsockopen(‘ssl://’.$url_info[‘host’], $port, $errno, $errstr, 30);
> иначе <
$port = isset($url_info[‘port’]) ? $url_info[‘порт’] : 80;
$fp=fsockopen($url_info[‘host’], $port, $errno, $errstr, 30);
>
Следует отметить, что вместо того, чтобы возвращать «false» в случае ошибки, эта функция (и другие) возвращает большое ПРЕДУПРЕЖДЕНИЕ, которое остановит ваш скрипт, если в нем нет ошибки. оповещение/предупреждение выкл.
Это безумие! Любая функция, которая делает что-то вроде получения URL-адреса, должна просто возвращать false без предупреждения, если URL-адрес не работает по какой-либо причине, кроме неправильного формата.
При запросе заголовка в качестве ассоциативного поля важно отметить, что заголовки, чувствительные к регистру, НЕ будут рассматриваться как одинаковые. Если ваше первое перенаправление содержит заголовок «местоположение», а второе содержит заголовок «местоположение» (обратите внимание на заглавную букву L), они будут отображаться как два разных ключа в вашем ассоциативном массиве.
Ниже приведена попытка создать альтернативу get_headers, нормализующую имена. заголовки, предоставляя ту же функциональность (с той же сигнатурой), что и собственная функция get_headers:
function getHeaders(string $location, bool $associative = true, $context = null ): поле уже найдено (
* уже хранился в массиве `results`) и
* является массивом, вставляем текущее значение.
*
* Если имя заголовка было найдено, но в настоящее время
* указывает на строку, мы заменяем ее массивом, но
* сохраняем исходную строку с индексом 0.
*/
if ( !key_exists ($key, $results)) <
$results [ $key ] = $value ;
> иначе если (is_array ($results [$key])) <
array_push($results [$key], $value);
> иначе <
$results [ $key ] = [ $results [ $key ], $value ];
>
// В заголовке не найдено ‘:’, поэтому оставим как есть.
$results [ $indexer ++ ] = $header ;
Следующий код НЕ РАБОТАЕТ с PHP версии 7.0.26 на моем сервере.
Возможно ли, что требуется какая-то другая конфигурация кода?
Пробовал с веб-страницами и локальным путем к файлу.
Теперь будет напечатано слово «Готово».
/**
* Мы можем использовать get_headers, чтобы проверить, является ли URL-адрес изображения фактическим источником изображения
* Просто проверьте, не является ли формат URL-адреса изображения небезопасным
* @param $link string
* @return boolean
*/
function checkImageContentType ($link) <
//Установите для второго параметра значение 1, затем получите значение «Content-Type»
$imgHeader = get_headers ($link, 1 );
if(!isset( $imgHeader [ ‘Content-Type’ ])) <
//В заголовке нет Content-Type, поэтому URL-адрес изображения не является фактическим источником изображения
return false ;
>
//Общий шаблон для проверки значения Content-Type
$imgPattern = ‘/^image\/(jpeg array();
>
$division markers = array ( );
foreach ($headers as $key => $h)
if (is_numeric ($key))
array_push ($splitmarks, $h);
> ;
>
// получаем «настоящие» заголовки
$headers_final = array();
$i = 0;
$headers = get_headers ($crawl_uri);
foreach ($headers as $head)
// если значение является одной из меток разделения, следующий заголовок начинается с
if ( array_key_exists ( $i , $splitmarks ) && $head === $splitmarks [ $i ] ) <
$i++;
>
плюс
// получаем имя заголовка
$tmp = Explosion( «:», $head, 2);
// проверяем если заголовок уже существует, если да, проанализируйте заголовки, подобные массиву
if (!empty ($headers_final [ $i — 1 ][ $tmp [ 0 ]]))
if (is_array ($headers_final [ $i — 1 ] [ $tmp [ 0]]))
array_push ($headers_final [ $i — 1 ][ $tmp [ 0 ]], $ tmp [ 1 ]);
>
плюс <
$headers_final [ $i — 1 ][ $tmp [ 0 ]] = array( $headers_final [ $i — 1 ][ $tmp [ 0 ]], $ tmp [ 1 ]);
>
>
плюс <
$headers_final [ $i — 1 ][ $tmp [ 0 ]] = $ тмп [ 1 ];
>
>
>
вернуть $headers_final ;
>
?>
Для тех, кто читает комментарии выше, вот некоторый код, который учитывает все вышеперечисленные предложения, а также включает исправление ошибки.
Этот код в основном предоставляет функции «get_headers» даже в системах, не использующих PHP 5.0. Используйте strtolower() для ключей, как было предложено. Используйте поле $h2 вместо $key, как было предложено. Убрать строку об отключении клавиши $; нет причин демонтировать то, что больше не используется. И я изменил заголовок статуса, чтобы он назывался «статус» в поле (вместо «0»). Обратите внимание, что если возвращается более одного непомеченного заголовка, они застревают в «статусе», но я думаю, что статус — это единственный заголовок, возвращаемый без тега, поэтому он работает для меня. Итак, сначала код, затем пример использования:
if(! function_exists (‘get_headers’)) <
/**
* @return array
* @param string $url
* @param int $format
* @desc Получить все заголовки
* @author cpurruc fh-landshut de
* @modified by dotpointer
* @modified by aeontech
*/
function get_headers ($url, $format = 0 ) <
$url_info = parse_url ( $url );
$port = isset( $url_info [‘порт’]) ? $url_info [‘порт’]: 80;
$fp = fsockopen ($url_info [‘хост’], $port, $errno, $errstr, 30);
если( $fp ) <
$head = «HEAD».@ $url_info [‘путь’]. «?» .@ $url_info [‘запрос’];
$голова .= » HTTP/1.0\r\nHost: » .@ $url_info [ ‘host’ ]. «\r\n\r\n»;
fputs ($fp, $head);
while(! feof ( $fp )) <
if( $header = trim ( fgets ( $fp , 1024 ))) <
if( $format == 1 ) <
$h2 = Explosion(‘: ‘, $header);
// первый элемент имеет тип заголовка http, например HTTP/1.1 200 OK,
// у него нет отдельного имени, поэтому нам нужно его проверить.
if( $h2 [ 0 ] = = $headers ) <
$headers [ ‘status’] = $header;
>
else <
$headers [ strtolower ($h2 [ 0 ])] = trim ($ h2 [ 1 ]);
>
>
else <
$headers [] = $header ;
>
>
>
возвращает $headers;
>
да нет <
возвращает false ;
>
>
>
?>
Вы в порядке? Вот использование:
= get_headers (‘http://www.example.com/’, 1);
if (! $response ) <
echo ‘Не удается установить соединение.’ ;
>
else <
print_r ( $response );
>
?>
Эта функция оказалась самой медленной для получения страницы header , вероятно, потому, что он использует запрос GET вместо запроса HEAD.Более 10 000 000 попыток получить заголовок страницы с сервера я обнаружил следующее (результаты в секундах).
cURL: Среднее значение: 0,584127946. Sigma: 0, 050581736.
fsocketopen: Среднее: 0,622114251. Сигма: 0,263170424.
get_headers: Среднее: 0,90375551. Сигма: 0,273823419.
cURL был самый быстрый, а fsocketopens был вторым самым быстрым. Я также заметил, что у fsocketopen были некоторые выбросы, а у cURL — нет.
В некоторых случаях вы не хотите, чтобы get_headers следовал за перенаправлениями. Например, некоторые из моих серверов могут получить доступ к определенной веб-странице, которая отправляет заголовок перенаправления. Однако страница, на которую вы перенаправляетесь, имеет брандмауэр. Мне нужно использовать перенаправление 302 и что-то сделать, чтобы получить новый URL-адрес, к которому я *могу* подключиться.
Следующее даст вам результат, аналогичный get_headers, за исключением того, что у него есть время ожидания и нет последующих перенаправлений:
function get_headers_curl ( $url )
<
$ch = curl_init();
curl_setopt ($channel, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HEADER,true);
curl_setopt($ch,CURLOPT_NOBODY,true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt ($ch, CURLOPT_TIMEOUT, 15);
$r = curl_exec ($ch);
$r = разделить («\n», $r);
вернуть $r ;
>
Если вы хотите отслеживать перенаправления, вы можете сделать что-то вроде этого:
function getNextLocation ($headers)
<
$array = $headers;
$count = count($array);
for ( $i = 0 ; $i $count ; $i ++)
<
if ( strpos ($array [ $i ], «location:» ))
<
$url = substr ($array [$i], 10);
>
>
если ($url)
<
вернуть $url;
>
плюс
<
возвращает 0 ;
>
>
?>
Проверка правильности URL-адреса, который предшествует одному или нескольким перенаправлениям сервера, является сложной задачей. Будет возвращено более одного кода состояния, и все, кроме первого, будут кодами перенаправления.
Эта функция возвращает целое число, содержащее трехзначный код состояния последнего возвращенного кода, что и требуется.
function getStatus($url) <
$headers = @get_headers($url, true);
$значение = NULL;
if ($headers === false) <
вернуть $headers;
>
foreach ($headers типа $k => $v) <
if (!is_int($k)) <
продолжить;
>
$значение = $v;
>
return (int) substr($value, strpos($value, ‘ ‘, 8) + 1, 3);
>
PHP выдает ошибку, если getHeaders() не работает. Попробуйте вернуть значение для === false.
В ответ на изменение решения Jamaz dotpointer.
Вот небольшая модификация вашей функции, которая добавляет эмуляцию необязательного параметра $format.
if(! function_exists (‘get_headers’)) <
/**
* @return array
* @param string $url
* @param int $format
* @desc Получить все заголовки
* @author cpurruc fh- ландшафт
* @modified by dotpointer
* @modified aeontech
*/
function get_headers ( $url , $format = 0 )
<
$url_info = parse_url (адрес $url);
$port = isset( $url_info [‘порт’]) ? $url_info [‘порт’]: 80;
$fp = fsockopen ($url_info [‘host’], $port, $errno, $errstr, 30);
if( $fp )
<
$head = «HEAD».@ $url_info [‘путь’]. «?» .@ $url_info [‘запрос’]. » HTTP/1.0\r\nHost: » .@ $url_info [‘host’]. «\r\n\r\n»;
fputs ($fp, $head);
while(! feof ($fp))
<
if( $header = trim ( fgets ( $fp , 1024 )))
<
if( $format == 1 )
<
$key = array_shift (взорвать (‘:’, $header));
// первый элемент — это тип заголовка http, например HTTP 200 OK,
// у него нет отдельного имени, поэтому нам нужно его проверить.
if( $key == $header )
<
$headers [] = $header ;
>
иначе
<
$headers [ $key ]= substr ($header, strlen ($key)+ 2);
>
отключено ( $key );
>
иначе
<
$headers [] = $header ;
>
>
>
вернуть $headers;
>
иначе
<
вернуть ложь;
>
>
>
?>
Content-Type возвращает значение, которое зависит только от расширения, а не от фактического MIME-TYPE.
Источник