Jak mogę sprawdzić, czy URL istnieje przez PHP?

Odpowiedzi:

296

Tutaj:

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

Od tutaj i tuż poniżej powyższego postu, tam curl rozwiązanie:

function url_exists($url) {
    if (!$fp = curl_init($url)) return false;
    return true;
}
karim79
źródło
18
Obawiam się, że sposób CURL nie zadziała w ten sposób. Sprawdź to: stackoverflow.com/questions/981954/…
viam0Zah
4
niektóre witryny mają inne $file_headers[0]strony błędów. na przykład youtube.com. jego strona błędu ma tę wartość jako HTTP/1.0 404 Not Found(różnica wynosi 1,0 i 1,1). co wtedy robić?
Krishna Raj K
21
Być może użycie strpos($headers[0], '404 Not Found')może załatwić sprawę
alexandru.topliceanu
12
@Mark zgodził się! Wyjaśnienie strpos($headers[0], '404')jest lepsze!
alexandru.topliceanu
1
@ karim79 uważaj na ataki SSRF i XSPA
M Rostami
55

Przy ustalaniu, czy istnieje adres URL z php, należy zwrócić uwagę na kilka rzeczy:

  • Czy sam adres URL jest prawidłowy (ciąg, nie pusty, dobra składnia), można to szybko sprawdzić po stronie serwera.
  • Oczekiwanie na odpowiedź może zająć trochę czasu i wykonanie kodu blokowego.
  • Nie wszystkie nagłówki zwrócone przez get_headers () są dobrze uformowane.
  • Użyj curl (jeśli możesz).
  • Zapobiegaj pobieraniu całego treści / treści, ale żądaj tylko nagłówków.
  • Rozważ przekierowanie adresów URL:
    • Czy chcesz zwrócić pierwszy kod?
    • Lub wykonaj wszystkie przekierowania i zwróć ostatni kod?
    • Możesz skończyć z 200, ale może przekierowywać za pomocą metatagów lub javascript. Ustalenie, co stanie się później, jest trudne.

Należy pamiętać, że niezależnie od zastosowanej metody oczekiwanie na odpowiedź wymaga czasu.
Cały kod może (i prawdopodobnie zostanie) zatrzymany, dopóki nie dowiesz się o wyniku lub nie upłynął limit czasu żądań.

Na przykład: poniższy kod może długo wyświetlać stronę, jeśli adresy URL są nieprawidłowe lub nieosiągalne:

<?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/>";
}

Poniższe funkcje mogą być pomocne, prawdopodobnie chcesz je zmodyfikować zgodnie z własnymi potrzebami:

    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
źródło
z jakiegoś powodu getHttpResponseCode_using_curl () zawsze zwraca 200 w moim przypadku.
TD_Nijboer
2
jeśli ktoś ma ten sam problem, sprawdź dns-nameservers .. użyj opendns bez żadnych podążających za nimi przekierowań stackoverflow.com/a/11072947/1829460
TD_Nijboer
+1 za bycie jedyną odpowiedzią na przekierowania. Zmieniono na, return $codeaby if($code == 200){return true;} return false;uporządkować tylko sukcesy
Birrel
@PKHunter: Nie. Mój szybki regex preg_match był prostym przykładem i nie pasuje do wszystkich wymienionych tam adresów URL. Zobacz ten testowy adres URL: regex101.com/r/EpyDDc/2 Jeśli chcesz lepszy, zastąp go adresem wymienionym na twoim linku ( mathiasbynens.be/demo/url-regex ) od diegoperini; wydaje się pasować do wszystkich, zobacz ten link testowy
MoonLite
46
$headers = @get_headers($this->_value);
if(strpos($headers[0],'200')===false)return false;

więc za każdym razem, gdy skontaktujesz się ze stroną internetową i zdobędziesz coś innego niż 200 ok, będzie działać

lunarnet76
źródło
13
Ale co, jeśli to przekierowanie? Domena jest nadal ważna, ale zostanie pominięta.
Eric Leroy,
4
Powyżej w jednym wierszu: return strpos(@get_headers($url)[0],'200') === false ? false : true. Może się przydać.
Dejv
$ to jest w PHP jest odniesieniem do bieżącego obiektu. Odwołanie: php.net/manual/en/language.oop5.basic.php Elementarz: phpro.org/tutorials/Object-Oriented-Programming-with-PHP.html Najprawdopodobniej fragment kodu został pobrany z klasy i nie został odpowiednio naprawiony .
Marc Witteveen,
18

nie możesz używać curl na niektórych serwerach. Możesz użyć tego kodu

<?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
źródło
może nie działać w przypadku przekierowania 302-303 lub na przykład 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'.
Randy Skretka
źródło
2
To nie zadziała, jeśli opcja allow-url-fopen jest wyłączona. - php.net/manual/en/…
Daniel Paul Searles
2
Sugerowałbym przeczytanie tylko pierwszego bajtu ... jeśli (@plik_get_koncentracje ($ url, false, NULL, 0,1))
Daniel Valland
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;
}
leela
źródło
8

Korzystam z tej funkcji:

/**
 * @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
źródło
5

Rozwiązanie get_headers () karim79 nie zadziałało, ponieważ uzyskałem szalone wyniki na 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] => 
) 

W każdym razie ten programista pokazuje, że cURL jest znacznie szybszy niż get_headers ():

http://php.net/manual/fr/function.get-headers.php#104723

Ponieważ wiele osób poprosiło karim79 o naprawienie rozwiązania CURL, oto rozwiązanie, które zbudowałem dzisiaj.

/**
* 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;
}

Pozwól mi wyjaśnić opcje zwijania:

CURLOPT_RETURNTRANSFER : zwraca ciąg zamiast wyświetlać stronę wywołującą na ekranie.

CURLOPT_SSL_VERIFYPEER : cUrl nie pobierze certyfikatu

CURLOPT_HEADER : dołącz nagłówek do ciągu

CURLOPT_NOBODY : nie dołączaj ciała do ciągu

CURLOPT_USERAGENT : niektóre strony potrzebują tego do poprawnego działania (na przykład: https://plus.google.com )


Uwaga dodatkowa : w tej funkcji używam wyrażenia regularnego Diego Periniego do sprawdzania poprawności adresu URL przed wysłaniem żądania:

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

Uwaga dodatkowa 2 : Rozbijam ciąg nagłówka i nagłówki użytkownika [0], aby upewnić się, że sprawdzam tylko kod powrotu i komunikat (przykład: 200, 404, 405 itd.)

Uwaga dodatkowa 3 : Czasami sprawdzenie tylko kodu 404 nie wystarczy (patrz test jednostkowy), więc istnieje opcjonalny parametr $ failCodeList, aby dostarczyć całą listę kodów do odrzucenia.

I, oczywiście, oto test jednostkowy (w tym wszystkie popularne sieci społecznościowe), który potwierdza moje kodowanie:

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"));
}

Wielki sukces dla wszystkich,

Jonathan Parent-Lévesque z Montrealu

Jonathan Parent Lévesque
źródło
4
function urlIsOk($url)
{
    $headers = @get_headers($url);
    $httpStatus = intval(substr($headers[0], 9, 3));
    if ($httpStatus<400)
    {
        return true;
    }
    return false;
}
Spir
źródło
3

całkiem szybko:

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');
Sebastian Lasse
źródło
Zbyt skomplikowane :) stackoverflow.com/questions/981954/…
Ja͢ck
dostaję ten wyjątek, gdy adres URL istnieje: Nie można wywołać CURLOPT_HEADERFUNCTION
safiot
3

Wszystkie powyższe rozwiązania + dodatkowy cukier. (Najlepsze rozwiązanie 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');
}

Przykład:

var_dump ( urlExists('http://stackoverflow.com/') );
// Output: true;
Junaid Atari
źródło
3

aby sprawdzić, czy adres URL jest online czy offline ---

function get_http_response_code($theURL) {
    $headers = @get_headers($theURL);
    return substr($headers[0], 9, 3);
}
Hosam Elzagh
źródło
3
function url_exists($url) {
    $headers = @get_headers($url);
    return (strpos($headers[0],'200')===false)? false:true;
}
Krishna Guragai
źródło
2

Oto rozwiązanie, które odczytuje tylko pierwszy bajt kodu źródłowego ... zwracanie wartości false, jeśli plik_get_contents zawiedzie ... Będzie to również działać dla zdalnych plików takich jak obrazy.

 function urlExists($url)
{
    if (@file_get_contents($url,false,NULL,0,1))
    {
        return true;
    }
    return false;
}
Daniel Valland
źródło
0

najprostszym sposobem jest zwijanie się (i SZYBCIEJ)

<?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
źródło
0

Innym sposobem sprawdzenia, czy adres URL jest prawidłowy, może być:

<?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;
      }
  }
?>
Antonio Carlos Barbosa
źródło
0

get_headers () zwraca tablicę z nagłówkami wysłanymi przez serwer w odpowiedzi na żądanie 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>';
}
Jeacovy Gayle
źródło
0

cURL może zwrócić kod HTTP Nie sądzę, aby cały ten dodatkowy kod był potrzebny?

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;
        }
    }
Arun Vitto
źródło
0

Jedną rzeczą, którą należy wziąć pod uwagę przy sprawdzaniu nagłówka dla 404, jest przypadek, gdy witryna nie generuje od razu 404.

Wiele witryn sprawdza, czy strona istnieje w źródle PHP / ASP (et cetera) i przekierowuje do strony 404. W takich przypadkach nagłówek jest zasadniczo przedłużany o nagłówek 404, który jest generowany. W takich przypadkach błąd 404 nie jest w pierwszym wierszu nagłówka, ale w dziesiątym.

$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
źródło
0

Przeprowadzam kilka testów, aby sprawdzić, czy linki w mojej witrynie są prawidłowe - ostrzega mnie, gdy osoby trzecie zmieniają swoje linki. Miałem problem z witryną, która miała źle skonfigurowany certyfikat, co oznaczało, że get_headers php nie działa.

Więc przeczytałem, że curl był szybszy i postanowiłem spróbować. wtedy miałem problem z linkedin, który dał mi błąd 999, który okazał się być problemem użytkownika użytkownika.

Nie obchodziło mnie, czy certyfikat nie jest ważny dla tego testu i nie obchodziło mnie, czy odpowiedź była przekierowaniem.

Potem pomyślałem, że i tak używam get_headers, jeśli curl zawodzi ....

Dać mu szansę....

/**
 * 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
źródło
-2

rodzaj starego wątku, ale .. robię to:

$file = 'http://www.google.com';
$file_headers = @get_headers($file);
if ($file_headers) {
    $exists = true;
} else {
    $exists = false;
}
hackdotslashdotkill
źródło
Sorta .. Ale nie do końca.
hackdotslashdotkill
jak twoja odpowiedź jest lepsza?
Jah
@Jah oczywiście nie jest na poziomie -2. Pewnie pewnej nocy opublikowałem to późno, kiedy byłem w
półśnie