34

I want to check whether a website is up or down at a particular instance using PHP. I came to know that curl will fetch the contents of the file but I don't want to read the content of the website. I just want to check the status of the website. Is there any way to check the status of the site? Can we use ping to check the status? It is sufficient for me to get the status signals like (404, 403, etc) from the server. A small snippet of code might help me a lot.

Nate
  • 30,286
  • 23
  • 113
  • 184
brainless
  • 5,698
  • 16
  • 59
  • 82

8 Answers8

50

something like this should work

    $url = 'yoururl';
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_exec($ch);
    $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if (200==$retcode) {
        // All's well
    } else {
        // not so much
    }
Jeff Busby
  • 2,001
  • 17
  • 12
  • 2
    I also prefer to set `CURLOPT_CONNECTTIMEOUT` and `CURLOPT_TIMEOUT` as well to lower values. – machineaddict Oct 18 '13 at 10:15
  • @machineaddict Do you mean to ouput "site offline" instead of wait for the connection? I don't see the difference between check 2 times for one thing and wait a few for the current operation. – m3nda Mar 13 '15 at 07:49
  • @machineaddict Even with CURLOPT_FOLLOWLOCATION set to true, it still returns a 301 return code... How is this possible? – Henry Harris Jun 18 '15 at 23:01
  • @HenryHarris: read [this](http://stackoverflow.com/questions/3890631/php-curl-with-curlopt-followlocation-error) and [this](http://stackoverflow.com/questions/6002272/curlopt-followlocation-not-working) – machineaddict Jun 19 '15 at 07:10
  • 2
    There are a lot more succcessful HTTP response codes than 200. https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success – carefulnow1 May 06 '17 at 15:18
18
curl -Is $url | grep HTTP | cut -d ' ' -f2

curl -Is $url outputs just the headers.

grep HTTP filters to the HTTP response header.

cut -d ' ' -f2 trims the output to the second "word", in this case the status code.

Example:

$ curl -Is google.com | grep HTTP | cut -d ' ' -f2
301
ratz
  • 197
  • 1
  • 2
  • 29
    When providing code that solves the problem, it is best to also give at least a short explanation of how it works so that folks reading won't have to mentally parse it line by line to understand the differences. – Fluffeh Sep 27 '12 at 11:17
10
function checkStatus($url) {
    $agent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; pt-pt) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27";

    // initializes curl session
    $ch = curl_init();

    // sets the URL to fetch
    curl_setopt($ch, CURLOPT_URL, $url);

    // sets the content of the User-Agent header
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);

    // make sure you only check the header - taken from the answer above
    curl_setopt($ch, CURLOPT_NOBODY, true);

    // follow "Location: " redirects
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

    // return the transfer as a string
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    // disable output verbose information
    curl_setopt($ch, CURLOPT_VERBOSE, false);

    // max number of seconds to allow cURL function to execute
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);

    // execute
    curl_exec($ch);

    // get HTTP response code
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    curl_close($ch);

    if ($httpcode >= 200 && $httpcode < 300)
        return true;
    else
        return false;
}
 
// how to use
//===================
if ($this->checkStatus("https://stackoverflow.com"))
    echo "Website is up";
else
    echo "Website is down";
exit;
David
  • 280
  • 1
  • 6
  • 15
Dinesh Rabara
  • 1,119
  • 12
  • 13
6

Here is how I did it. I set the user agent to minimize the chance of the target banning me and also disabled SSL verification since I know the target:

private static function checkSite( $url ) {
    $useragent = $_SERVER['HTTP_USER_AGENT'];

    $options = array(
            CURLOPT_RETURNTRANSFER => true,      // return web page
            CURLOPT_HEADER         => false,     // do not return headers
            CURLOPT_FOLLOWLOCATION => true,      // follow redirects
            CURLOPT_USERAGENT      => $useragent, // who am i
            CURLOPT_AUTOREFERER    => true,       // set referer on redirect
            CURLOPT_CONNECTTIMEOUT => 2,          // timeout on connect (in seconds)
            CURLOPT_TIMEOUT        => 2,          // timeout on response (in seconds)
            CURLOPT_MAXREDIRS      => 10,         // stop after 10 redirects
            CURLOPT_SSL_VERIFYPEER => false,     // SSL verification not required
            CURLOPT_SSL_VERIFYHOST => false,     // SSL verification not required
    );
    $ch = curl_init( $url );
    curl_setopt_array( $ch, $options );
    curl_exec( $ch );

    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ($httpcode == 200);
}
Daniel Szalay
  • 4,041
  • 12
  • 57
  • 103
5

Have you seen the get_headers() function ? http://it.php.net/manual/en/function.get-headers.php . It seems to do exactly what you need.

If you use curl directly with the -I flag, it will return the HTTP headers (404 etc) instead of the page HTML. In PHP, the equivalent is the curl_setopt($ch, CURLOPT_NOBODY, 1); option.

Michael Low
  • 24,276
  • 16
  • 82
  • 119
5

ping won't do what you're looking for - it will only tell you if the machine is up (and responding to ping). That doesn't necessarily mean that the webserver is up, though.

You might want to try using the http_head method - it'll retrieve the headers that the webserver sends back to you. If the server is sending back headers, then you know it's up and running.

girasquid
  • 15,121
  • 2
  • 48
  • 58
  • This embedded hyperlink http://ca.php.net/http_head redirects to http://ca.php.net/manual-lookup.php?pattern=http_head&lang=en&scope=404quickref which the following message: ***http_head** doesn't exist. Closest matches:*. The answer needs to be edited in order to contain the correct reference. – Funk Forty Niner Mar 09 '18 at 17:16
  • @FunkFortyNiner Thanks, fixed the link – girasquid May 30 '18 at 15:16
3

You can not test a webserver with ping, because its a different service. The server may running, but the webserver-daemon may be crashed anyway. So curl is your friend. Just ignore the content.

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
0

This function checks whether a URL exists or not. The time of the check is a maximum of 300ms, but you can change that parameter within the cURL option CURLOPT_TIMEOUT_MS

/*
 * Check is URL exists
 *
 * @param  $url           Some URL
 * @param  $strict        You can add it true to check only HTTP 200 Response code
 *                        or you can add some custom response code like 302, 304 etc.
 *
 * @return boolean true or false
 */
function is_url_exists($url, $strict = false)
{
    if (is_int($strict) && $strict >= 100 && $strict < 600 || is_array($strict)) {
        if(is_array($strict)) {
            $response = $strict;
        } else {
            $response = [$strict];
        }
    } else if ($strict === true || $strict === 1) {
        $response = [200];
    } else {
        $response = [200,202,301,302,303];
    }
    $ch = curl_init( $url );
    
    $options = [
        CURLOPT_NOBODY          => true,
        CURLOPT_FAILONERROR     => true,
        CURLOPT_RETURNTRANSFER  => true,
        CURLOPT_NOSIGNAL        => true,
        CURLOPT_SSL_VERIFYPEER  => false,
        CURLOPT_SSL_VERIFYHOST  => false,
        CURLOPT_HEADER          => false,
        CURLOPT_FOLLOWLOCATION  => true,
        CURLOPT_VERBOSE         => false,
        CURLOPT_USERAGENT       => ( $_SERVER['HTTP_USER_AGENT'] ?? '' ),
        CURLOPT_TIMEOUT_MS      => 300, // TImeout in miliseconds
        CURLOPT_MAXREDIRS       => 2,
    ];
    
    curl_setopt_array($ch, $options);
    
    $return = curl_exec($ch);
    $errno = curl_errno($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    curl_close($ch);
    
    if (!$errno && $return !== false) {
        return ( in_array($httpcode, $response) !== false );
    }
    
    return false;
}

You can check any URL, from domain, ip address to images, files, etc. I think this is the fastest way and proven useful.

Ivijan Stefan Stipić
  • 6,249
  • 6
  • 45
  • 78