Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как правильно использовать get_headers?
 
 автор: Владимир55   (16.02.2015 в 18:08)   письмо автору
 
 

Считываение заголовка производится так:
 if (!get_headers($url)) echo "<font color='#FF0000'> Wowa</font>"; 

При этом, в случае отсутствия страницы выводится сообщение об ошибке вида:

Warning: get_headers(http://zaok.ru/) [0function.get-headers0]: failed to open stream: HTTP request failed!

Если же проверять на существование
 if (!isset(get_headers($url))) echo "<font color='#FF0000'> Wowa</font>"; 

то получаем сообщение
Fatal error: Can't use function return value in write context

Как корректно использовать get_headers, чтобы все работало и при этом избежать этих сообщений?

(Использовать @ не хочется).

  Ответить  
 
 автор: Tamplier   (18.02.2015 в 11:12)   письмо автору
 
   для: Владимир55   (16.02.2015 в 18:08)
 

Лови функцию по отлову статуса, написал как то для своих целей


function getStatus($url,$info = false){
$arr = @get_headers('http://'.$url, 1);
if(!empty($arr[0])){ foreach($arr as $key => $val){
if(!is_array($val)){ if(preg_match("'^HTTP/\d'iu", $val)){
    $a = preg_replace("'HTTP/([0-9\.])+ (\d+)\s([\w\d\s]+)'iu", ($info == true) ? "\$2\$3" : "\$2", $val); 
}}} return $a; } else { return false; }
}


Пользуемся так:


echo getStatus('zaok.ru');


В ответ получишь код статуса, если - 200 то все путем
Если другой ответ, думай и анализируй, справка по кодам статуса тут - https://support.google.com/webmasters/answer/40132?hl=ru

P.S. Если у кого есть полезные дополнения или оптимизации данной функции, напишите.

  Ответить  
 
 автор: Trianon   (18.02.2015 в 15:00)   письмо автору
 
   для: Tamplier   (18.02.2015 в 11:12)
 

крайне не понравилось, что применяется foreach. Тем самым допускается анализ [оставшихся] полей заголовка помимо строки статуса.

  Ответить  
 
 автор: Tamplier   (18.02.2015 в 16:00)   письмо автору
 
   для: Trianon   (18.02.2015 в 15:00)
 

У вас есть более элегантное решение?
С удовольствием бы на него взглянул (правда интересно, без малейшей иронии)...

  Ответить  
 
 автор: Sfinks   (18.02.2015 в 17:49)   письмо автору
 
   для: Tamplier   (18.02.2015 в 16:00)
 

Хоть вы и не меня спрашивали, но например вот:
<?php

  
function getStatus($url){

    
$url trim($url);

    if(
preg_match('/^https?:\/\//'$url)){
      
$domain preg_replace('/^.+\/\/([^\/]+).*$/''$1'$url);
    }
    else{
      
$domain preg_replace('/^([^\/]+).*$/''$1'$url);
      
$url 'http://'.$url;
    }
    if(
gethostbyname($domain) === $domain) return 'host not found';   # <-- тут

    
$headers get_headers($url1);
    return (int)
preg_replace('/^.+?\s(\d+).+$/i''$1'$headers[0]);
  }

  echo 
getStatus('яяяяяяяяяя.рф');
  echo 
'<br>';
  echo 
getStatus('http://softtime.ru/forum/index.php?id_forum=1');

И, кстати, вопрос изначально был не в этом. Ваша функция абсолютно не решает поставленную задачу.
Строка, в которой есть ответ для топикстартера помечена камментом.

  Ответить  
 
 автор: Tamplier   (18.02.2015 в 18:44)   письмо автору
 
   для: Sfinks   (18.02.2015 в 17:49)
 

Ну почему же вопрос был не в этом, насколько я понял, человек просто простукивает сайт и в случае если сайт недоступен, выводит сообщение (если я правильно понял). И код статуса тут наиболее предпочтителен, т.к. позволяет не только узнать доступен сайт или нет, но и что ответил сервер (если к примеру, мы стабильно получаем 5хх ошибки, значит сайт лежит).

К слову ваша функция спотыкается на 30х кодах, вы выхватываете первое значение статуса, а оно может быть и переадресацией. К примеру вот что выдает get_headers по сайту Яндекса:


Array
(
    [0] => HTTP/1.1 302 Found
    [Date] => Array
        (
            [0] => Wed, 18 Feb 2015 15:36:16 GMT
            [1] => Wed, 18 Feb 2015 15:36:16 GMT
        )

    [Location] => http://www.yandex.ru/
    [Vary] => Accept-Encoding
    [Content-Type] => Array
        (
            [0] => text/html; charset=iso-8859-1
            [1] => text/html; charset=UTF-8
        )

    [X-Pad] => avoid browser bug
    [Content-Length] => Array
        (
            [0] => 205
            [1] => 58742
        )

    [1] => HTTP/1.1 200 Ok
    [Server] => nginx
    [Connection] => close
    [Cache-Control] => no-cache,no-store,max-age=0,must-revalidate
    [Expires] => Wed, 18 Feb 2015 15:36:17 GMT
    [Last-Modified] => Wed, 18 Feb 2015 15:36:17 GMT
    [Content-Security-Policy] => default-src 'self' 'unsafe-inline' 'unsafe-eval' wss://portal-xiva.yandex.net *.yandex.ru yandex.ru *.yandex.net https://*.yandex.ru https://yandex.ru https://*.yandex.net yandex.st yastatic.net *.yastatic.net ws://portal-xiva.yandex.net wss://portal-xiva.yandex.net wss://push.yandex.ru; img-src data: 'self' *.yandex.ru *.tns-counter.ru *.gemius.pl https://*.yandex.ru https://*.tns-counter.ru https://*.gemius.pl yandex.st *.yandex.net yastatic.net *.yastatic.net; report-uri http://www.yandex.ru/log/csp?from=big.ru&showid=20945.27471.1424273776.64526&h=i7&yu=7307228561424273777;
    [P3P] => policyref="/w3c/p3p.xml", CP="NON DSP ADM DEV PSD IVDo OUR IND STP PHY PRE NAV UNI"
    [Set-Cookie] => Array
        (
            [0] => yandex_gid=213; Expires=Fri, 20-Mar-2015 15:36:16 GMT; Domain=.yandex.ru; Path=/
            [1] => yp=; Expires=Sun, 20-Feb-2005 15:36:16 GMT; Path=/
            [2] => yp=; Expires=Sun, 20-Feb-2005 15:36:16 GMT; Domain=.www.yandex.ru; Path=/
            [3] => yp=1426865777.ygu.1; Expires=Sat, 15-Feb-2025 15:36:16 GMT; Domain=.yandex.ru; Path=/
            [4] => yandexuid=7307228561424273777; Expires=Sat, 15-Feb-2025 15:36:16 GMT; Domain=.yandex.ru; Path=/
        )

    [X-Frame-Options] => DENY
    [X-XRDS-Location] => http://openid.yandex.ru/server_xrds/
)


Ваша функция выдает 302 код, а по идее должна выдавать 200, поскольку идет корректная переадресация, с 200 кодом в конце.

  Ответить  
 
 автор: Sfinks   (18.02.2015 в 19:56)   письмо автору
 
   для: Tamplier   (18.02.2015 в 18:44)
 

Ладно, про 3хх забыл. Допилю чуть позже. А ТС спрашивал, как не получать WARNING не пользуясь при этом @ если адрес не существует.
Цитата:
> (Использовать @ не хочется).
Возможно вы правы и ему нужно и то и другое

  Ответить  
 
 автор: Sfinks   (18.02.2015 в 22:25)   письмо автору
 
   для: Tamplier   (18.02.2015 в 18:44)
 

Можно так:
<?php
  
function getStatus($url){
    
// убираю все проверки, чтоб место не занимать
    // но по факту они должны быть.
    
$headers get_headers($url1);
    
$last_numeric_key max(array_filter(array_keys($headers), 'is_numeric'));
    return (int)
preg_replace('/^.+?\s(\d+).+$/i''$1'$headers[$last_numeric_key]);
  }
но это все извращение. Не надо изобретать велосипед.

  Ответить  
 
 автор: Sfinks   (18.02.2015 в 22:50)   письмо автору
 
   для: Sfinks   (18.02.2015 в 22:25)
 

<?php

  
function getStatus($url){
    
// тут и проверок не надо
    
$c curl_init($url);
    
curl_setopt_array($c, array(
      
CURLOPT_NOBODY => true,
      
CURLOPT_FOLLOWLOCATION => true
    
));
    
curl_exec($c);
    
$code curl_getinfo($cCURLINFO_HTTP_CODE);
    
curl_close($c);
    return 
$code;
  }

  echo 
getStatus('yandex.ru').'<br>';
  echo 
getStatus('http://яяяяяяяяяя.рф').'<br>';
  echo 
getStatus('izvestia.ru/news/1000000').'<br>';
  echo 
getStatus('http://softtime.ru/forum/index.php?id_forum=1');
это вместо велосипеда с get_headers()
200
0
404
200

  Ответить  
 
 автор: Tamplier   (19.02.2015 в 10:01)   письмо автору
 
   для: Sfinks   (18.02.2015 в 22:25)
 

Спасибо большое за идею с ключами, выкинул из своей функции foreach и добавил вашу проверку ключей.

  Ответить  
 
 автор: Trianon   (18.02.2015 в 21:29)   письмо автору
 
   для: Tamplier   (18.02.2015 в 16:00)
 

>У вас есть более элегантное решение?

Очевидно, вызвать get_headers в контексте запрещенного follow_location и сыром - безключевом формате. Вернуть 0-й элемент массива. Ну или код статуса из него.

Ответ 302 - тоже ответ. И несет информацию чуть большую, чем просто (200 и неважно, сколько до этого 200 скакать.)

То недокументированное блядство, которое возвращает get_headers() при включенном follow_;location, выбешивает неиллюзорно. Но это к разработчикам, понятное дело.

  Ответить  
 
 автор: Tamplier   (19.02.2015 в 15:19)   письмо автору
 
   для: Trianon   (18.02.2015 в 21:29)
 

> Ответ 302 - тоже ответ. И несет информацию чуть большую, чем просто (200 и неважно, сколько до этого 200 скакать.)

Ну смотря для каких целей использовать функцию, для себя писал указанный выше вариант, поскольку был нужен конечный ответ (т.е. в данном случае код 200).

> То недокументированное блядство, которое возвращает get_headers() при включенном follow_;location, выбешивает неиллюзорно. Но это к разработчикам, понятное дело.

Это да, первый раз когда узрел эту кашу, долго чесал затылок и думал, как со всем этим работать...

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования