Существование документа на удаленном сервере

Talker

Новичок
Существование документа на удаленном сервере

Глупый вопрос, как это лучше всего проверять? Делаю file($url), если что-то возвращает, то документ есть. Как-то криво, а ничего лучше найти не могу...
 

denver

?>Скриптер
PHP:
if($sock=fsockopen('example.org', 80)) {
  fputs($sock, "HEAD /index.html HTTP/1.0\r\n\r\n");
  echo fgets($sock);
}
 

Talker

Новичок
Спасибо. Если файл существует, то выдается только HTTP/1.1 200 OK, или может быть что-то ещё?
 

Talker

Новичок
функция
PHP:
function check_exists($url)
{
	if($sock=@fsockopen($url, 80)) {
	  fputs($sock, "HEAD / HTTP/1.0\r\n\r\n"); 
	  if (preg_match ("/(\d{3})/", fgets($sock), $match))  {
		 	return $match[1];
		}
	}
	return -1;
}
работает как надо, но для всех народных сайтов выдает 404. Это проблема в скрипте, или в Народе? :confused:
 

Talker

Новичок
От того, что убрал @ и поставил
PHP:
ini_set('display_errors',1);
error_reporting(E_ALL);
ничего не изменилось, сообщений об ошибке как не было, так и нет, а народ на все запросы ывдает 404.
В логах сервера тоже нет ошибок.
Если не трудно, попробуй запустить эту функцию с любым народным сайтом в качестве параметра.
 

Talker

Новичок
Автор оригинала: kruglov
А где HOST-заголовок?
А это надо если он стоит в откытии сокета? :confused:

Поставил
PHP:
"HEAD http://$url/ HTTP/1.0\r\n\r\n"
Теперь работает. Вот бы ещё понять почему. :rolleyes:
Всем спасибо. Пошел учить матчасть :)
 

kruglov

Новичок
На народе на 1 ipшнике тыщи сайтов. Как народ узнает, какой из них показывать?
 

Talker

Новичок
Автор оригинала: kruglov
На народе на 1 ipшнике тыщи сайтов. Как народ узнает, какой из них показывать?
Так я запрашиваю не IP, а конкретный домен (т.е. субдомен)
 

kruglov

Новичок
Talker
Где? Во fsockopen? Он только производит соединение. Ему все равно, напишете вы туда IP-адрес или доменное имя. Получив второе, PHP дернет DNS, получит от него IPшник и "задача сводится к предыдущей".
 

Gorynych

Посетитель PHP-Клуба
1)

ну во-первых, если уж дергать сокет, то по HTTP/1.1 (потому что при множестве виртуальных хостов на ОДНОМ адресе запрос ПО_УМОЛЧАНИЮ получает (сюрприз!) умолчательный хост)

так что правим это дело:
Код:
function check_exists($url) {
    $metaUrl = parse_url($url);
    if ( !isset($metaUrl['host']) ) {
        return false;
    }
    $request = $metaUrl['path'];
    if ( !$request ) {
        $request = '/';
    }
    if ( isset($metaUrl['query']) ) {
        $request .= "?".$metaUrl['query'];
    }
    if ( isset($metaUrl['fragment']) ) {
        $request .= "#".$metaUrl['fragment'];
    }
    $request = "HEAD ".$request." HTTP/1.1\r\nHost: ".$metaUrl['host']."\r\n\r\n";

    if( ($sock=@fsockopen($metaUrl['host'], 80, $errno, $errstr, 30)) ) {
        $contents = '';
        fputs($sock, $request);
        while( ($buf = fgets($sock)) ) {
            $contents .= $buf;
        }
        if ( !$contents || preg_match ("/HTTP\/1\.1 ([4-5]\d{2})/", $contents, $match) ) {
            return false;
        }

        if (preg_match ("/HTTP\/1\.1 (\d{3})/", $contents, $match))  {
            return $match[1];
        }
    }
    return false;
}
о статус кодах возврата смотрим тут - http://www.w3.org/Protocols/HTTP/HTRESP.html

2)

но вообще-то в PHP есть CURL (Client URL Library Functions) http://ru.php.net/curl
 
Сверху