Как я могу проверить, существует ли URL через PHP?

Ответы:

297

Вот:

$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;
}

От здесь и прямо под постом выше, есть завиток решение:

function url_exists($url) {
    if (!$fp = curl_init($url)) return false;
    return true;
}
karim79
источник
18
Я боюсь, что CURL-путь не будет работать таким образом. Проверьте это: stackoverflow.com/questions/981954/…
viam0Zah
4
некоторые сайты имеют разные $file_headers[0]страницы ошибок. например, youtube.com. его страница ошибки имеет это значение как HTTP/1.0 404 Not Found(разница составляет 1,0 и 1,1). что делать то?
Кришна Радж К
21
Возможно, использование strpos($headers[0], '404 Not Found')может сделать трюк
alexandru.topliceanu
12
@ Марк согласился! Чтобы уточнить, strpos($headers[0], '404')лучше!
alexandru.topliceanu
1
@ karim79 будь осторожен с атаками SSRF и XSPA
М Ростами
55

При выяснении, существует ли 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;
    }
Moonlite
источник
по какой-то причине getHttpResponseCode_using_curl () всегда возвращает 200 в моем случае.
TD_Nijboer
2
если у кого-то есть такая же проблема, проверьте dns-nameservers .. используйте opendns без перенаправлений stackoverflow.com/a/11072947/1829460
TD_Nijboer
+1 для того, чтобы быть единственным ответом, чтобы иметь дело с перенаправлениями. Поменял на, return $codeчтобы if($code == 200){return true;} return false;перебирать только успехи
Birrel
@PKHunter: Нет. Мое быстрое регулярное выражение preg_match было простым примером и не будет соответствовать всем URL-адресам, перечисленным там. Посмотрите этот тестовый URL: regex101.com/r/EpyDDc/2 Если вы хотите лучший вариант , замените его на тот, который указан в вашей ссылке ( mathiasbynens.be/demo/url-regex ) из diegoperini; похоже, что все они совпадают, см. эту тестовую ссылку: regex101.com/r/qMQp23/1
MoonLite
46
$headers = @get_headers($this->_value);
if(strpos($headers[0],'200')===false)return false;

так что каждый раз, когда вы обращаетесь к веб-сайту и получаете что-то еще, кроме 200, это будет работать

lunarnet76
источник
13
Но что, если это перенаправление? Домен все еще действителен, но будет пропущен.
Эрик Леруа
4
Выше на одной строке: return strpos(@get_headers($url)[0],'200') === false ? false : true. Может быть полезным.
Дейв
$ this в PHP - это ссылка на текущий объект. Ссылка: php.net/manual/en/language.oop5.basic.php Учебник для начинающих : phpro.org/tutorials/Object-Oriented-Programming-with-PHP.html Скорее всего, фрагмент кода был взят из класса и не исправлен соответствующим образом ,
Марк Виттевин
18

Вы не можете использовать 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';
  }
?>
Minhaz
источник
он может не работать для перенаправления 302-303 или, например, 304 Not Modified
Zippp
8
$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'.
Рэнди Скретка
источник
2
Это не будет работать, если allow-url-fopen выключен. - php.net/manual/en/…
Даниэль Пол
2
Я бы предложил прочитать только первый байт ... if (@file_get_contents ($ url, false, NULL, 0,1))
Даниэль Валланд,
8
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;
}
лила
источник
8

Я использую эту функцию:

/**
 * @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";
    }
}
Ehsan
источник
5

Решение 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"));
}

Большой успех всем,

Джонатан Родитель-Левеск из Монреаля

Джонатан Родитель Левеск
источник
4
function urlIsOk($url)
{
    $headers = @get_headers($url);
    $httpStatus = intval(substr($headers[0], 9, 3));
    if ($httpStatus<400)
    {
        return true;
    }
    return false;
}
Спир
источник
3

достаточно быстро:

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');
Себастьян Лассе
источник
Слишком сложно :) stackoverflow.com/questions/981954/…
Ja͢ck
я получаю это исключение, когда URL существует: не удалось вызвать CURLOPT_HEADERFUNCTION
safiot
3

Все вышеперечисленные решения + дополнительный сахар. (Окончательное решение 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;
Джунаид Атари
источник
3

проверить, если URL-адрес онлайн или оффлайн ---

function get_http_response_code($theURL) {
    $headers = @get_headers($theURL);
    return substr($headers[0], 9, 3);
}
Хосам Эльзаг
источник
3
function url_exists($url) {
    $headers = @get_headers($url);
    return (strpos($headers[0],'200')===false)? false:true;
}
Кришна Гурагай
источник
2

Вот решение, которое читает только первый байт исходного кода ... возвращает false, если file_get_contents завершается неудачно ... Это также будет работать для удаленных файлов, таких как изображения.

 function urlExists($url)
{
    if (@file_get_contents($url,false,NULL,0,1))
    {
        return true;
    }
    return false;
}
Даниэль Валланд
источник
0

простой способ - это curl (и FASTER тоже)

<?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';}

?>
T.Todua
источник
0

Другой способ проверить, является ли 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;
      }
  }
?>
Антонио Карлос Барбоса
источник
0

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>';
}
Джеаков Гэйл
источник
0

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;
        }
    }
Арун Витто
источник
0

Когда вы проверяете заголовок для 404, нужно учитывать одну вещь: случай, когда сайт не генерирует 404 сразу.

Многие сайты проверяют, существует ли страница в источнике PHP / ASP (и так далее), и перенаправляют вас на страницу 404. В этих случаях заголовок в основном расширяется заголовком генерируемого 404. В этих случаях ошибка 404 не в первой строке заголовка, а в десятой.

$array = get_headers($url);
$string = $array[0];
print_r($string) // would generate:

Array ( 
[0] => HTTP/1.0 301 Moved Permanently 
[1] => Date: Fri, 09 Nov 2018 16:12:29 GMT 
[2] => Server: Apache/2.4.34 (FreeBSD) LibreSSL/2.7.4 PHP/7.0.31 
[3] => X-Powered-By: PHP/7.0.31 
[4] => Set-Cookie: landing=%2Freed-diffuser-fig-pudding-50; path=/; HttpOnly 
[5] => Location: /reed-diffuser-fig-pudding-50/ 
[6] => Content-Length: 0 
[7] => Connection: close 
[8] => Content-Type: text/html; charset=utf-8 
[9] => HTTP/1.0 404 Not Found 
[10] => Date: Fri, 09 Nov 2018 16:12:29 GMT 
[11] => Server: Apache/2.4.34 (FreeBSD) LibreSSL/2.7.4 PHP/7.0.31 
[12] => X-Powered-By: PHP/7.0.31 
[13] => Set-Cookie: landing=%2Freed-diffuser-fig-pudding-50%2F; path=/; HttpOnly 
[14] => Connection: close 
[15] => Content-Type: text/html; charset=utf-8 
) 
Lexib0y
источник
0

Я запускаю несколько тестов, чтобы увидеть, являются ли ссылки на моем сайте действительными - предупреждает меня, когда третьи лица изменяют свои ссылки. У меня была проблема с сайтом, у которого был плохо настроенный сертификат, из-за которого php get_headers не работал.

Итак, я прочитал, что завиток был быстрее, и решил попробовать. затем у меня возникла проблема с linkedin, которая выдала мне ошибку 999, которая оказалась проблемой агента пользователя.

Мне было все равно, если сертификат не действителен для этого теста, и мне было все равно, если ответ был перенаправлен.

Тогда я решил использовать get_headers в любом случае, если curl не работает ....

Попробуй....

/**
 * returns true/false if the $url is present.
 *
 * @param string $url assumes this is a valid url.
 *
 * @return bool
 */
private function url_exists (string $url): bool
{
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_NOBODY, TRUE);             // this does a head request to make it faster.
  curl_setopt($ch, CURLOPT_HEADER, TRUE);             // just the headers
  curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, FALSE);  // turn off that pesky ssl stuff - some sys admins can't get it right.
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  // set a real user agent to stop linkedin getting upset.
  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36');
  curl_exec($ch);
  $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  if (($http_code >= HTTP_OK && $http_code < HTTP_BAD_REQUEST) || $http_code === 999)
  {
    curl_close($ch);
    return TRUE;
  }
  $error = curl_error($ch); // used for debugging.
  curl_close($ch);
  // just try the get_headers - it might work!
  stream_context_set_default(array('http' => array('method' => 'HEAD')));
  $file_headers = @get_headers($url);
  if ($file_headers)
  {
    $response_code = substr($file_headers[0], 9, 3);
    return $response_code >= 200 && $response_code < 400;
  }
  return FALSE;
}
pgee70
источник
-2

своего рода старая тема, но .. я делаю это:

$file = 'http://www.google.com';
$file_headers = @get_headers($file);
if ($file_headers) {
    $exists = true;
} else {
    $exists = false;
}
hackdotslashdotkill
источник
Сорта .. Но не совсем.
hackdotslashdotkill
как твой ответ лучше?
Jah
@ Да, это явно не в -2. Я, вероятно, написал это поздно вечером, когда я был в полусне после того, как весь день смотрел на экраны ..
hackdotslashdotkill