복붙노트

PHP에서 404에 대한 URL을 테스트하는 쉬운 방법은 무엇입니까?

PHP

PHP에서 404에 대한 URL을 테스트하는 쉬운 방법은 무엇입니까?

나 자신에게 몇 가지 기본적인 긁적 거리기를 가르치고 있는데, 때때로 코드가 404로 돌아가는 URL이 404의 나머지 코드를 껌으로 채워주는 것을 발견했다.

따라서 코드 상단에 URL이 404를 반환하는지 확인하는 테스트가 필요합니다.

이것은 매우 간단한 작업처럼 보이지만 Google은 나에게 어떤 대답도하지 않습니다. 나는 잘못된 것들을 찾고 있다고 걱정한다.

한 블로그가 이것을 사용하도록 권장했습니다.

$valid = @fsockopen($url, 80, $errno, $errstr, 30);

비어있는 경우 $ valid인지 확인하십시오.

하지만 문제가되는 URL에 리디렉션이 포함되어 있으므로 모든 값에 대해 $ valid가 비어 있습니다. 아니면 내가 뭔가 잘못하고있는 것 같아.

또한 "헤드 요청"을 살펴 보았지만 아직 실제 코드 예제를 찾아서 사용해 보았습니다.

제안? 그리고 이것이 컬에 관한 무엇입니까?

해결법

  1. ==============================

    1.PHP의 curl 바인딩을 사용하는 경우 curl_getinfo를 다음과 같이 사용하여 오류 코드를 확인할 수 있습니다.

    PHP의 curl 바인딩을 사용하는 경우 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. */
    
  2. ==============================

    2.php5를 실행하는 경우 다음을 사용할 수 있습니다.

    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
    }
    

    W3C 코드 및 정의

  3. ==============================

    3.strager의 코드를 사용하면 CURLINFO_HTTP_CODE에서 다른 코드를 확인할 수 있습니다. 일부 웹 사이트는 404를 신고하지 않고 맞춤 404 페이지로 리디렉션하고 302 (리디렉션) 또는 유사한 것을 반환합니다. 나는 실제 파일 (예 : robots.txt)이 서버에 존재하는지 확인하는 데이 파일을 사용했습니다. 분명히 이런 종류의 파일은 존재한다면 리다이렉트를 일으키지 않을 것이지만 그렇지 않으면 404 페이지로 리다이렉트 할 것이다. 내가 전에 말했듯이 404 코드는 없을 것이다.

    strager의 코드를 사용하면 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;
        }
    }
    
  4. ==============================

    4.strager가 암시 하듯이 cURL을 사용하십시오. curl_setopt로 CURLOPT_NOBODY를 설정하여 전체 페이지 다운로드를 건너 뛸 수도 있습니다. 헤더 만 있으면됩니다.

    strager가 암시 하듯이 cURL을 사용하십시오. curl_setopt로 CURLOPT_NOBODY를 설정하여 전체 페이지 다운로드를 건너 뛸 수도 있습니다. 헤더 만 있으면됩니다.

  5. ==============================

    5.가장 쉬운 솔루션을 찾고 있다면 한 가지 방법을 시도해 볼 수 있습니다.

    가장 쉬운 솔루션을 찾고 있다면 한 가지 방법을 시도해 볼 수 있습니다.

    file_get_contents('www.yoursite.com');
    //and check by echoing
    echo $http_response_header[0];
    
  6. ==============================

    6.나는이 대답을 여기에서 발견했다.

    나는이 대답을 여기에서 발견했다.

    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) {
            case 200:
                    $error_status="200: Success";
                    break;
            case 401:
                    $error_status="401: Login failure.  Try logging out and back in.  Password are ONLY used when posting.";
                    break;
            case 400:
                    $error_status="400: Invalid request.  You may have exceeded your rate limit.";
                    break;
            case 404:
                    $error_status="404: Not found.  This shouldn't happen.  Please let me know what happened using the feedback link above.";
                    break;
            case 500:
                    $error_status="500: Twitter servers replied with an error. Hopefully they'll be OK soon!";
                    break;
            case 502:
                    $error_status="502: Twitter servers may be down or being upgraded. Hopefully they'll be OK soon!";
                    break;
            case 503:
                    $error_status="503: Twitter service unavailable. Hopefully they'll be OK soon!";
                    break;
            default:
                    $error_status="Undocumented error: " . $status_code;
                    break;
        }
    

    기본적으로 "파일 가져 오기"메서드를 사용하여 http 응답 헤더 변수에 상태 코드를 자동으로 채우는 URL을 검색합니다.

  7. ==============================

    7.성능을 고려하여 이들 세 가지 방법을 테스트했습니다.

    성능을 고려하여 이들 세 가지 방법을 테스트했습니다.

    결과는 적어도 내 테스트 환경에서 :

    컬 성공

    이 테스트는 헤더 (noBody) 만 필요하다는 고려하에 수행됩니다. 자신을 시험해보십시오.

    $url = "http://de.wikipedia.org/wiki/Pinocchio";
    
    $start_time = microtime(TRUE);
    $headers = get_headers($url);
    echo $headers[0]."<br>";
    $end_time = microtime(TRUE);
    echo $end_time - $start_time."<br>";
    
    
    $start_time = microtime(TRUE);
    $response = file_get_contents($url);
    echo $http_response_header[0]."<br>";
    $end_time = microtime(TRUE);
    echo $end_time - $start_time."<br>";
    
    $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."<br>";
    curl_close($handle);
    $end_time = microtime(TRUE);
    echo $end_time - $start_time."<br>";
    
  8. ==============================

    8.훌륭한 대답에 대한 추가 힌트로서 :

    훌륭한 대답에 대한 추가 힌트로서 :

    제안 된 솔루션의 변형을 사용할 때 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 설정에 정의 된 값으로 되돌립니다.

  9. ==============================

    9.이 코드를 사용하여 링크의 상태를 볼 수도 있습니다.

    이 코드를 사용하여 링크의 상태를 볼 수도 있습니다.

    <?php
    
    function get_url_status($url, $timeout = 10) 
    {
    $ch = curl_init();
    // set cURL options
    $opts = array(CURLOPT_RETURNTRANSFER => 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');
    ?>
    
  10. ==============================

    10.

    <?php
    
    $url= 'www.something.com';
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, true);   
    curl_setopt($ch, CURLOPT_NOBODY, true);    
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.4");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_TIMEOUT,10);
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    $output = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    
    echo $httpcode;
    ?>
    
  11. ==============================

    11.다음은 간단한 해결책입니다.

    다음은 간단한 해결책입니다.

    $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을 사용하는 모든 것으로 변경할 수 있습니다.

  12. ==============================

    12.이것은 단지 코드 조각입니다. 희망이 당신을 위해 일합니다.

    이것은 단지 코드 조각입니다. 희망이 당신을 위해 일합니다.

                $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'];
    
  13. ==============================

    13.모든 오류를 잡기 : 4XX 및 5XX, 나는이 작은 스크립트를 사용합니다 :

    모든 오류를 잡기 : 4XX 및 5XX, 나는이 작은 스크립트를 사용합니다 :

    function URLIsValid($URL){
        $headers = @get_headers($URL);
        preg_match("/ [45][0-9]{2} /", (string)$headers[0] , $match);
        return count($match) === 0;
    }
    
  14. ==============================

    14.url이 200을 반환하지 않으면 true가됩니다. OK

    url이 200을 반환하지 않으면 true가됩니다. OK

    function check_404($url) {
       $headers=get_headers($url, 1);
       if ($headers[0]!='HTTP/1.1 200 OK') return true; else return false;
    }
    
  15. from https://stackoverflow.com/questions/408405/easy-way-to-test-a-url-for-404-in-php by cc-by-sa and MIT license