- Простой способ проверить URL-адрес для 404 в PHP?
- Простой способ проверки статуса 404
- 5 последних уроков рубрики "PHP"
- Фильтрация данных с помощью zend-filter
- Контекстное экранирование с помощью zend-escaper
- Подключение Zend модулей к Expressive
- Совет: отправка информации в Google Analytics через API
- Подборка PHP песочниц
- Easy way to test a URL for 404 in PHP?
- 15 Answers 15
Простой способ проверить URL-адрес для 404 в PHP?
Я преподаю себе некоторые базовые выскабливания, и я обнаружил, что иногда URL-адреса, которые я передаю в мой код, возвращают 404, что задирает весь остальной код.
Поэтому мне нужно проверить в верхней части кода, чтобы проверить, возвращает ли URL 404 или нет.
Это похоже на довольно прямолинейную задачу, но Google не дает мне никаких ответов. Я беспокоюсь, что искал неправильный материал.
В одном блоге рекомендуется использовать это:
$valid = @fsockopen($url, 80, $errno, $errstr, 30);
а затем проверить, есть ли $ valid, если пусто или нет.
Но я думаю, что URL-адрес, который дает мне проблемы, имеет перенаправление на него, поэтому значение $ valid становится пустым для всех значений. Или, возможно, я делаю что-то еще неправильно.
Я также рассмотрел «запрос главы», но мне еще не удалось найти какие-либо примеры кода, с которыми я могу играть или попробовать.
Предложения? И что это за скручивание?
Если вы используете привязки curl PHP, вы можете проверить код ошибки с помощью curl_getinfo как таковой:
$handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 404) < /* Handle 404 here. */ >curl_close($handle); /* Handle $response here. */
Если вы используете php5, вы можете использовать:
$url = 'http://www.example.com'; print_r(get_headers($url, 1));
Кроме того, с помощью php4 пользователь внес вклад в следующее:
/** This is a modified version of code from "stuart at sixletterwords dot com", at 14-Sep-2005 04:52. This version tries to emulate get_headers() function at PHP4. I think it works fairly well, and is simple. It is not the best emulation available, but it works. Features: - supports (and requires) full URLs. - supports changing of default port in URL. - stops downloading from socket as soon as end-of-headers is detected. Limitations: - only gets the root URL (see line with "GET / HTTP/1.1"). - don't support HTTPS (nor the default HTTPS port). */ if(!function_exists('get_headers')) < function get_headers($url,$format=0) < $url=parse_url($url); $end = "\r\n\r\n"; $fp = fsockopen($url['host'], (empty($url['port'])?80:$url['port']), $errno, $errstr, 30); if ($fp) < $out = "GET / HTTP/1.1\r\n"; $out .= "Host: ".$url['host']."\r\n"; $out .= "Connection: Close\r\n\r\n"; $var = ''; fwrite($fp, $out); while (!feof($fp)) < $var.=fgets($fp, 1280); if(strpos($var,$end)) break; >fclose($fp); $var=preg_replace("/\r\n\r\n.*\$/",'',$var); $var=explode("\r\n",$var); if($format) < foreach($var as $i) < if(preg_match('/^([a-zA-Z -]+): +(.*)$/',$i,$parts)) $v[$parts[1]]=$parts[2]; >return $v; > else return $var; > > >
Оба результата будут иметь следующий результат:
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 )
Поэтому вы можете просто проверить, что ответ заголовка был ОК, например:
$headers = get_headers($url, 1); if ($headers[0] == 'HTTP/1.1 200 OK') < //valid >if ($headers[0] == 'HTTP/1.1 301 Moved Permanently') < //moved or redirect page >
С кодом строгана вы также можете проверить CURLINFO_HTTP_CODE для других кодов. Некоторые веб-сайты не сообщают о 404, а просто перенаправляют на пользовательскую страницу 404 и возвращают 302 (перенаправление) или что-то подобное. Я использовал это, чтобы проверить, существует ли на сервере фактический файл (например, robots.txt) или нет. Очевидно, что этот вид файла не вызвал бы перенаправления, если бы он существовал, но если бы он этого не сделал, он перенаправил бы на страницу 404, которая, как я уже сказал, может не иметь кода 404.
function is_404($url) < $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); curl_close($handle); /* If the document has loaded successfully without any redirection or error */ if ($httpCode >= 200 && $httpCode < 300) < return false; >else < return true; >>
Как предлагает strager, изучите использование cURL. Вы также можете быть заинтересованы в установке CURLOPT_NOBODY с curl_setopt, чтобы пропустить загрузку всей страницы (вам просто нужны заголовки).
Если вы ищете самое простое решение и которое вы можете попробовать в один раз на php5, сделайте
file_get_contents('www.yoursite.com'); //and check by echoing echo $http_response_header[0];
if(($twitter_XML_raw=file_get_contents($timeline))==false)< // Retrieve HTTP status code list($version,$status_code,$msg) = explode(' ',$http_response_header[0], 3); // Check the HTTP Status code switch($status_code)
По сути, вы используете метод «получить содержимое» для получения URL-адреса, который автоматически заполняет переменную заголовка ответа HTTP с кодом состояния.
В качестве дополнительного намека на большой принятый ответ:
При использовании варианта предлагаемого решения я получил ошибки из-за установки php «max_execution_time». Итак, я сделал следующее:
set_time_limit(120); $curl = curl_init($url); curl_setopt($curl, CURLOPT_NOBODY, true); $result = curl_exec($curl); set_time_limit(ini_get('max_execution_time')); curl_close($curl);
Сначала я установил ограничение по времени на большее количество секунд, в конце я вернул его к значению, определенному в настройках php.
добавлено, проверено эти 3 метода с учетом производительности.
Результат, по крайней мере, в моей тестовой среде:
Керл побеждает
Этот тест проводится с учетом того, что нужны только заголовки (noBody). Попробуй себя:
$url = "http://de.wikipedia.org/wiki/Pinocchio"; $start_time = microtime(TRUE); $headers = get_headers($url); echo $headers[0]."
"; $end_time = microtime(TRUE); echo $end_time - $start_time."
"; $start_time = microtime(TRUE); $response = file_get_contents($url); echo $http_response_header[0]."
"; $end_time = microtime(TRUE); echo $end_time - $start_time."
"; $start_time = microtime(TRUE); $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($handle, CURLOPT_NOBODY, 1); // and *only* get the header /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); // if($httpCode == 404) < // /* Handle 404 here. */ // >echo $httpCode."
"; curl_close($handle); $end_time = microtime(TRUE); echo $end_time - $start_time."
";
Вы также можете использовать этот код, чтобы увидеть статус любой ссылки:
true, // do not output to browser CURLOPT_URL => $url, // set URL CURLOPT_NOBODY => true, // do a HEAD request only CURLOPT_TIMEOUT => $timeout); // set timeout curl_setopt_array($ch, $opts); curl_exec($ch); // do it! $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); // find HTTP status curl_close($ch); // close handle echo $status; //or return $status; //example checking if ($status == '302') < echo 'HEY, redirection';>> get_url_status('http://yourpage.comm'); ?>
$handle = curl_init($uri); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($handle,CURLOPT_HTTPHEADER,array ("Accept: application/rdf+xml")); curl_setopt($handle, CURLOPT_NOBODY, true); curl_exec($handle); $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 200||$httpCode == 303) < echo "you might get a reply"; >curl_close($handle);
В вашем случае вы можете изменить application/rdf+xml на все, что вы используете.
это просто и фрагмент кода, надежда работает для вас
$ch = @curl_init(); @curl_setopt($ch, CURLOPT_URL, 'http://example.com'); @curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"); @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); @curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = @curl_exec($ch); $errno = @curl_errno($ch); $error = @curl_error($ch); $response = $response; $info = @curl_getinfo($ch); return $info['http_code'];
Чтобы поймать все ошибки: 4XX и 5XX, я использую этот маленький скрипт:
function URLIsValid($URL) < $headers = @get_headers($URL); preg_match("/ [45]2/", (string)$headers[0] , $match); return count($match) === 0; >
Простой способ проверки статуса 404
Для получения подробной информации о запросе, можно обратиться к curl_getinfo:
$handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Запрос */ $response = curl_exec($handle); /* Проверка на статус 404 (не найдено). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 404) < /* Обработка 404 */ >curl_close($handle); /* Обработка $response */
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://stackoverflow.com/questions/408405/easy-way-to-test-a-url-for-404-in-php
Перевел: Станислав Протасевич
Урок создан: 5 Июля 2015
Просмотров: 7022
Правила перепечатки
5 последних уроков рубрики "PHP"
Фильтрация данных с помощью zend-filter
Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Контекстное экранирование с помощью zend-escaper
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Подключение Zend модулей к Expressive
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Совет: отправка информации в Google Analytics через API
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.
Easy way to test a URL for 404 in PHP?
I'm teaching myself some basic scraping and I've found that sometimes the URL's that I feed into my code return 404, which gums up all the rest of my code. So I need a test at the top of the code to check if the URL returns 404 or not. This would seem like a pretty straightfoward task, but Google's not giving me any answers. I worry I'm searching for the wrong stuff. One blog recommended I use this:
$valid = @fsockopen($url, 80, $errno, $errstr, 30);
and then test to see if $valid if empty or not. But I think the URL that's giving me problems has a redirect on it, so $valid is coming up empty for all values. Or perhaps I'm doing something else wrong. I've also looked into a "head request" but I've yet to find any actual code examples I can play with or try out. Suggestions? And what's this about curl?
15 Answers 15
If you are using PHP's curl bindings, you can check the error code using curl_getinfo as such:
$handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); /* Get the HTML or whatever is linked in $url. */ $response = curl_exec($handle); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); if($httpCode == 404) < /* Handle 404 here. */ >curl_close($handle); /* Handle $response here. */
I'm not familiar with cURL yet, so I'm missing a few concepts. What do I do with the $response variable down below? What does it contain?
@bflora, I made a mistake in the code. (Will fix in a second.) You can see the documentation for curl_exec on PHP's site.
@bflora $response will contain the content of the $url so you can do additional things like checking the content for specific strings or whatever. In your case, you just care about the 404 state, so you probably do not need to worry about $response.
@patrick then you need to specify curl_setopt($handle, CURLOPT_NOBODY, true); before running curl_exec
If your running php5 you can use:
$url = 'http://www.example.com'; print_r(get_headers($url, 1));
Alternatively with php4 a user has contributed the following:
/** This is a modified version of code from "stuart at sixletterwords dot com", at 14-Sep-2005 04:52. This version tries to emulate get_headers() function at PHP4. I think it works fairly well, and is simple. It is not the best emulation available, but it works. Features: - supports (and requires) full URLs. - supports changing of default port in URL. - stops downloading from socket as soon as end-of-headers is detected. Limitations: - only gets the root URL (see line with "GET / HTTP/1.1"). - don't support HTTPS (nor the default HTTPS port). */ if(!function_exists('get_headers')) < function get_headers($url,$format=0) < $url=parse_url($url); $end = "\r\n\r\n"; $fp = fsockopen($url['host'], (empty($url['port'])?80:$url['port']), $errno, $errstr, 30); if ($fp) < $out = "GET / HTTP/1.1\r\n"; $out .= "Host: ".$url['host']."\r\n"; $out .= "Connection: Close\r\n\r\n"; $var = ''; fwrite($fp, $out); while (!feof($fp)) < $var.=fgets($fp, 1280); if(strpos($var,$end)) break; >fclose($fp); $var=preg_replace("/\r\n\r\n.*\$/",'',$var); $var=explode("\r\n",$var); if($format) < foreach($var as $i) < if(preg_match('/^([a-zA-Z -]+): +(.*)$/',$i,$parts)) $v[$parts[1]]=$parts[2]; >return $v; > else return $var; > > >
Both would have a result similar to:
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 )
Therefore you could just check to see that the header response was OK eg:
$headers = get_headers($url, 1); if ($headers[0] == 'HTTP/1.1 200 OK') < //valid >if ($headers[0] == 'HTTP/1.1 301 Moved Permanently') < //moved or redirect page >