18 ответов:
здесь:
$file = 'http://www.domain.com/somefile.jpg'; $file_headers = @get_headers($file); if(!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') { $exists = false; } else { $exists = true; }С здесь и ниже выше сообщение, есть curl устранение:
function url_exists($url) { if (!$fp = curl_init($url)) return false; return true; }
при выяснении, существует ли url-адрес из php, есть несколько вещей, на которые следует обратить внимание:
- является ли сам url допустимым (строка, а не пустой, хороший синтаксис), это быстро проверить на стороне сервера.
- ожидание ответа может занять некоторое время и заблокировать выполнение кода.
- не все заголовки, возвращаемые get_headers() хорошо сформированы.
- используйте curl (если можете).
- предотвратите извлечение всего тела / содержимого, но только запросите заголовки.
- рассмотрите возможность перенаправления URL-адресов:
- вы хотите, чтобы первый код возвращается?
- или выполните все перенаправления и верните последний код?
- вы можете получить 200, но он может перенаправить с помощью мета-тегов или javascript. Выяснить, что происходит после этого, сложно.
имейте в виду, что какой бы метод вы используете, нужно время, чтобы дождаться ответа.
Весь код может (и, вероятно, будет) останавливаться до тех пор, пока вы либо знать результат, либо запросы истекли.например: приведенный ниже код может занять много времени для отображения страницы, если URL-адреса недействительны или недоступны:
<?php $urls = getUrls(); // some function getting say 10 or more external links foreach($urls as $k=>$url){ // this could potentially take 0-30 seconds each // (more or less depending on connection, target site, timeout settings...) if( ! isValidUrl($url) ){ unset($urls[$k]); } } echo "yay all done! now show my site"; foreach($urls as $url){ echo "<a href=\"{$url}\">{$url}</a><br/>"; }функции ниже могут быть полезны, вы, вероятно, хотите изменить их в соответствии с вашими потребностями:
function isValidUrl($url){ // first do some quick sanity checks: if(!$url || !is_string($url)){ return false; } // quick check url is roughly a valid http request: ( http://blah/... ) if( ! preg_match('/^http(s)?:\/\/[a-z0-9-]+(\.[a-z0-9-]+)*(:[0-9]+)?(\/.*)?$/i', $url) ){ return false; } // the next bit could be slow: if(getHttpResponseCode_using_curl($url) != 200){ // if(getHttpResponseCode_using_getheaders($url) != 200){ // use this one if you cant use curl return false; } // all good! return true; } function getHttpResponseCode_using_curl($url, $followredirects = true){ // returns int responsecode, or false (if url does not exist or connection timeout occurs) // NOTE: could potentially take up to 0-30 seconds , blocking further code execution (more or less depending on connection, target site, and local timeout settings)) // if $followredirects == false: return the FIRST known httpcode (ignore redirects) // if $followredirects == true : return the LAST known httpcode (when redirected) if(! $url || ! is_string($url)){ return false; } $ch = @curl_init($url); if($ch === false){ return false; } @curl_setopt($ch, CURLOPT_HEADER ,true); // we want headers @curl_setopt($ch, CURLOPT_NOBODY ,true); // dont need body @curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true); // catch output (do NOT print!) if($followredirects){ @curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,true); @curl_setopt($ch, CURLOPT_MAXREDIRS ,10); // fairly random number, but could prevent unwanted endless redirects with followlocation=true }else{ @curl_setopt($ch, CURLOPT_FOLLOWLOCATION ,false); } // @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,5); // fairly random number (seconds)... but could prevent waiting forever to get a result // @curl_setopt($ch, CURLOPT_TIMEOUT ,6); // fairly random number (seconds)... but could prevent waiting forever to get a result // @curl_setopt($ch, CURLOPT_USERAGENT ,"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1"); // pretend we're a regular browser @curl_exec($ch); if(@curl_errno($ch)){ // should be 0 @curl_close($ch); return false; } $code = @curl_getinfo($ch, CURLINFO_HTTP_CODE); // note: php.net documentation shows this returns a string, but really it returns an int @curl_close($ch); return $code; } function getHttpResponseCode_using_getheaders($url, $followredirects = true){ // returns string responsecode, or false if no responsecode found in headers (or url does not exist) // NOTE: could potentially take up to 0-30 seconds , blocking further code execution (more or less depending on connection, target site, and local timeout settings)) // if $followredirects == false: return the FIRST known httpcode (ignore redirects) // if $followredirects == true : return the LAST known httpcode (when redirected) if(! $url || ! is_string($url)){ return false; } $headers = @get_headers($url); if($headers && is_array($headers)){ if($followredirects){ // we want the the last errorcode, reverse array so we start at the end: $headers = array_reverse($headers); } foreach($headers as $hline){ // search for things like "HTTP/1.1 200 OK" , "HTTP/1.0 200 OK" , "HTTP/1.1 301 PERMANENTLY MOVED" , "HTTP/1.1 400 Not Found" , etc. // note that the exact syntax/version/output differs, so there is some string magic involved here if(preg_match('/^HTTP\/\S+\s+([1-9][0-9][0-9])\s+.*/', $hline, $matches) ){// "HTTP/*** ### ***" $code = $matches[1]; return $code; } } // no HTTP/xxx found in headers: return false; } // no headers : return false; }
$headers = @get_headers($this->_value); if(strpos($headers[0],'200')===false)return false;Так что в любое время вы обратитесь на сайт и получить что-то еще, чем 200 ОК это будет работать
вы не можете использовать curl на некоторых серверах вы можете использовать этот код
<?php $url = 'http://www.example.com'; $array = get_headers($url); $string = $array[0]; if(strpos($string,"200")) { echo 'url exists'; } else { echo 'url does not exist'; } ?>
$url = 'http://google.com'; $not_url = 'stp://google.com'; if (@file_get_contents($url)): echo "Found '$url'!"; else: echo "Can't find '$url'."; endif; if (@file_get_contents($not_url)): echo "Found '$not_url!"; else: echo "Can't find '$not_url'."; endif; // Found 'http://google.com'!Can't find 'stp://google.com'.
function URLIsValid($URL) { $exists = true; $file_headers = @get_headers($URL); $InvalidHeaders = array('404', '403', '500'); foreach($InvalidHeaders as $HeaderVal) { if(strstr($file_headers[0], $HeaderVal)) { $exists = false; break; } } return $exists; }
Я использую эту функцию:
/** * @param $url * @param array $options * @return string * @throws Exception */ function checkURL($url, array $options = array()) { if (empty($url)) { throw new Exception('URL is empty'); } // list of HTTP status codes $httpStatusCodes = array( 100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-Status', 208 => 'Already Reported', 226 => 'IM Used', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Switch Proxy', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Payload Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Unordered Collection', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 449 => 'Retry With', 450 => 'Blocked by Windows Parental Controls', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 509 => 'Bandwidth Limit Exceeded', 510 => 'Not Extended', 511 => 'Network Authentication Required', 599 => 'Network Connect Timeout Error' ); $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); if (isset($options['timeout'])) { $timeout = (int) $options['timeout']; curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); } curl_exec($ch); $returnedStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (array_key_exists($returnedStatusCode, $httpStatusCodes)) { return "URL: '{$url}' - Error code: {$returnedStatusCode} - Definition: {$httpStatusCodes[$returnedStatusCode]}"; } else { return "'{$url}' does not exist"; } }
решение get_headers () karim79 не сработало для меня, поскольку я получил сумасшедшие результаты с Pinterest.
get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed Array ( [url] => https://www.pinterest.com/jonathan_parl/ [exists] => ) get_headers(): Failed to enable crypto Array ( [url] => https://www.pinterest.com/jonathan_parl/ [exists] => ) get_headers(https://www.pinterest.com/jonathan_parl/): failed to open stream: operation failed Array ( [url] => https://www.pinterest.com/jonathan_parl/ [exists] => )в любом случае, этот разработчик демонстрирует, что cURL намного быстрее, чем get_headers ():
http://php.net/manual/fr/function.get-headers.php#104723
так как многие люди просили karim79 исправить это решение cURL, вот решение, которое я построил сегодня.
/** * Send an HTTP request to a the $url and check the header posted back. * * @param $url String url to which we must send the request. * @param $failCodeList Int array list of code for which the page is considered invalid. * * @return Boolean */ public static function isUrlExists($url, array $failCodeList = array(404)){ $exists = false; if(!StringManager::stringStartWith($url, "http") and !StringManager::stringStartWith($url, "ftp")){ $url = "https://" . $url; } if (preg_match(RegularExpression::URL, $url)){ $handle = curl_init($url); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($handle, CURLOPT_HEADER, true); curl_setopt($handle, CURLOPT_NOBODY, true); curl_setopt($handle, CURLOPT_USERAGENT, true); $headers = curl_exec($handle); curl_close($handle); if (empty($failCodeList) or !is_array($failCodeList)){ $failCodeList = array(404); } if (!empty($headers)){ $exists = true; $headers = explode(PHP_EOL, $headers); foreach($failCodeList as $code){ if (is_numeric($code) and strpos($headers[0], strval($code)) !== false){ $exists = false; break; } } } } return $exists; }позвольте мне объяснить завиток опции:
CURLOPT_RETURNTRANSFER: возвращает строку вместо отображения вызывающей страницы на экране.
параметра curlopt_ssl_verifypeer: cUrl не будет проверять сертификат
CURLOPT_HEADER: включить заголовок в строку
CURLOPT_NOBODY: не включайте тело в строку
CURLOPT_USERAGENT: некоторые сайт нуждается в этом, чтобы функционировать правильно (на примере:https://plus.google.com)
дополнительная информация: в этой функции я использую регулярное выражение Диего Перини для проверки URL перед отправкой запроса:
const URL = "%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.[a-z\x{00a1}-\x{ffff}]{2,6}))(?::\d+)?(?:[^\s]*)?$%iu"; //@copyright Diego Periniдополнительное примечание 2: я разнесу строку заголовка и заголовки пользователей[0], чтобы убедиться, что вы проверяете только код возврата и сообщение (пример: 200, 404, 405 и т. д.)
дополнительное Примечание 3: когда-нибудь проверка только кода 404 недостаточно (см. модульный тест), поэтому есть необязательный параметр $failCodeList для предоставления всего списка кода для отклонения.
и, конечно же, вот модульный тест (включая все популярные социальные сети), чтобы узаконить мое кодирование:
public function testIsUrlExists(){ //invalid $this->assertFalse(ToolManager::isUrlExists("woot")); $this->assertFalse(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque4545646456")); $this->assertFalse(ToolManager::isUrlExists("https://plus.google.com/+JonathanParentL%C3%A9vesque890800")); $this->assertFalse(ToolManager::isUrlExists("https://instagram.com/mariloubiz1232132/", array(404, 405))); $this->assertFalse(ToolManager::isUrlExists("https://www.pinterest.com/jonathan_parl1231/")); $this->assertFalse(ToolManager::isUrlExists("https://regex101.com/546465465456")); $this->assertFalse(ToolManager::isUrlExists("https://twitter.com/arcadefire4566546")); $this->assertFalse(ToolManager::isUrlExists("https://vimeo.com/**($%?%$", array(400, 405))); $this->assertFalse(ToolManager::isUrlExists("https://www.youtube.com/user/Darkjo666456456456")); //valid $this->assertTrue(ToolManager::isUrlExists("www.google.ca")); $this->assertTrue(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque")); $this->assertTrue(ToolManager::isUrlExists("https://plus.google.com/+JonathanParentL%C3%A9vesque")); $this->assertTrue(ToolManager::isUrlExists("https://instagram.com/mariloubiz/")); $this->assertTrue(ToolManager::isUrlExists("https://www.facebook.com/jonathan.parentlevesque")); $this->assertTrue(ToolManager::isUrlExists("https://www.pinterest.com/")); $this->assertTrue(ToolManager::isUrlExists("https://regex101.com")); $this->assertTrue(ToolManager::isUrlExists("https://twitter.com/arcadefire")); $this->assertTrue(ToolManager::isUrlExists("https://vimeo.com/")); $this->assertTrue(ToolManager::isUrlExists("https://www.youtube.com/user/Darkjo666")); }успехов всем,
Jonathan Parent-Lévesque из Монреаля
довольно быстро:
function http_response($url){ $resURL = curl_init(); curl_setopt($resURL, CURLOPT_URL, $url); curl_setopt($resURL, CURLOPT_BINARYTRANSFER, 1); curl_setopt($resURL, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback'); curl_setopt($resURL, CURLOPT_FAILONERROR, 1); curl_exec ($resURL); $intReturnCode = curl_getinfo($resURL, CURLINFO_HTTP_CODE); curl_close ($resURL); if ($intReturnCode != 200 && $intReturnCode != 302 && $intReturnCode != 304) { return 0; } else return 1; } echo 'google:'; echo http_response('http://www.google.com'); echo '/ ogogle:'; echo http_response('http://www.ogogle.com');
все вышеуказанные решения + дополнительный сахар. (Окончательное решение AIO)
/** * Check that given URL is valid and exists. * @param string $url URL to check * @return bool TRUE when valid | FALSE anyway */ function urlExists ( $url ) { // Remove all illegal characters from a url $url = filter_var($url, FILTER_SANITIZE_URL); // Validate URI if (filter_var($url, FILTER_VALIDATE_URL) === FALSE // check only for http/https schemes. || !in_array(strtolower(parse_url($url, PHP_URL_SCHEME)), ['http','https'], true ) ) { return false; } // Check that URL exists $file_headers = @get_headers($url); return !(!$file_headers || $file_headers[0] === 'HTTP/1.1 404 Not Found'); }пример:
var_dump ( urlExists('http://stackoverflow.com/') ); // Output: true;
function urlIsOk($url) { $headers = @get_headers($url); $httpStatus = intval(substr($headers[0], 9, 3)); if ($httpStatus<400) { return true; } return false; }
вот решение, которое читает только первый байт исходного кода... возвращает false, если file_get_contents не удается... Это также будет работать для удаленных файлов, таких как изображения.
function urlExists($url) { if (@file_get_contents($url,false,NULL,0,1)) { return true; } return false; }
чтобы проверить, если url находится в сети или в автономном режиме - - -
function get_http_response_code($theURL) { $headers = @get_headers($theURL); return substr($headers[0], 9, 3); }
простой способ-завиток (и быстрее тоже)
<?php $mylinks="http://site.com/page.html"; $handlerr = curl_init($mylinks); curl_setopt($handlerr, CURLOPT_RETURNTRANSFER, TRUE); $resp = curl_exec($handlerr); $ht = curl_getinfo($handlerr, CURLINFO_HTTP_CODE); if ($ht == '404') { echo 'OK';} else { echo 'NO';} ?>
другой способ проверить, если URL-адрес является действительным или нет можно:
<?php if (isValidURL("http://www.gimepix.com")) { echo "URL is valid..."; } else { echo "URL is not valid..."; } function isValidURL($url) { $file_headers = @get_headers($url); if (strpos($file_headers[0], "200 OK") > 0) { return true; } else { return false; } } ?>
функция get_headers() возвращает массив с заголовками, отправленными сервером в ответ на HTTP-запрос.
$image_path = 'https://your-domain.com/assets/img/image.jpg'; $file_headers = @get_headers($image_path); //Prints the response out in an array //print_r($file_headers); if($file_headers[0] == 'HTTP/1.1 404 Not Found'){ echo 'Failed because path does not exist.</br>'; }else{ echo 'It works. Your good to go!</br>'; }
function url_exists($url) { $headers = @get_headers($url); return (strpos($headers[0],'200')===false)? false:true; }
cURL может возвращать HTTP-код я не думаю, что весь этот дополнительный код необходим?
function urlExists($url=NULL) { if($url == NULL) return false; $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if($httpcode>=200 && $httpcode<300){ return true; } else { return false; } }
Comments