Skip to Content
Menu

is_available()

Check if a remote URL is online or down.

PHP March 30, 2021

Usage

PHP
nebula()->is_available($url, $nocache, $lookup_only, $args)

Parameters

$url
(Required) (String) The URL to check
Default: None

$allow_cache
(Optional) (Boolean) Whether to bypass the cache
Default: true

$allow_remote_request
(Optional) (Boolean) Allow actually calling the requested URL to check availability
Default: true

$args
(Optional) (Array) An array of request arguments
Default: array('redirection' => 5)

Parameter Notes

When false, $allow_remote_request will only check if the resource has been unavailable in the last 10 minutes. If the resource was unavailable, it will return false, otherwise it will return true (even if the resource is not available because it doesn’t actually check). This optimizes some calls because if the resource is available, it won’t need to be accessed twice. To use this properly, the resource must handle setting the “nebula_site_available_” transient manually.

For the $args array, refer to the WordPress documentation for individual parameters.

Request or provide clarification »

Examples

PHP
<?php if ( nebula()->is_available('https://www.example.com/file.txt') ){
    //Do something with the URL (like wp_remote_get).
} ?>

Demo


Example.com is currently online.
SpacerGIF.org is currently offline. Note: This domain shows that is_available() cannot pass "robot checks".
/r/Syracuse is currently offline.

https://rsi.com (a randomly generated domain) exists!

Additional Notes

This function caches the hostname (not the full URL) for 10 minutes. So whether the hostname is available or times out, that will be cached for 10 minutes unless the $allow_cache parameter is set to false. This means if a remote server is down, there will be a 5-10 second timeout (typically) once per hostname within 10 minutes.

Nebula’s remote_get() function builds this in so no manual transient needs to be maintained.

Note: This request may not pass “robot checks”, so a remote request may fail with a 503 response code.

Was this page helpful? Yes No


    A feedback message is required to submit this form.


    Please check that you have entered a valid email address.

    Enter your email address if you would like a response.

    Thank you for your feedback!

    Source File

    Located in /libs/Utilities/Utilities.php on line 1074.

    1 Hook

    Find these filters and actions in the source code below to hook into them. Use do_action() and add_filter() in your functions file or plugin.

    Filters
    "pre_nebula_is_available"
    Need a new filter hook? Request one here.

    Actions
    This function has no action hooks available. Request one?

    Note: This function contains 1 to-do comment.

    PHP
            public function is_available($url=null, $allow_cache=true, $allow_remote_request=true, $args=array()){
                $override = apply_filters('pre_nebula_is_available', null, $url, $allow_cache, $allow_remote_request);
                if ( isset($override) ){return $override;}
    
                //Make sure the URL is valid
                if ( empty($url) || strpos($url, 'http') !== 0 ){ //@todo "Nebula" 0: Update strpos() to str_contains() in PHP8
                    trigger_error('Error: Requested URL is either empty or missing acceptable protocol.', E_USER_ERROR);
                    return false;
                }
    
                $timer_name = $this->timer('Is Available (' . $url . ')', 'start', 'Is Available');
                $hostname = str_replace('.', '_', $this->url_components('hostname', $url)); //The hostname label for transients
    
                if ( $this->is_transients_enabled() ){
                    //Check transient first
                    $site_available_buffer = get_transient('nebula_site_available_' . $hostname);
                    if ( !empty($site_available_buffer) && $allow_cache ){ //If this hostname was found in a transient and specifically allowing a cached response.
                        if ( $site_available_buffer === 'Available' ){
                            set_transient('nebula_site_available_' . $hostname, 'Available', MINUTE_IN_SECONDS*30); //Re-up the transient with a 30 minute expiration
                            $this->timer($timer_name, 'end');
                            return true; //This hostname has worked within the last 30 minutes
                        }
    
                        set_transient('nebula_site_available_' . $hostname, 'Unavailable', MINUTE_IN_SECONDS*15); //15 minute expiration
                        $this->timer($timer_name, 'end');
                        return false; //This hostname has not worked within the last 15 minutes
                    }
                } else {
                    $allow_remote_request = false; //If transients are being suspended, don't pre-check if URLs are available
                }
    
                //Make an actual request to the URL if: the transient was empty or specifically requested a non-cached response, and specifically allowing a lookup
                //Ex: remote_get() prevents this from running the actual request to avoid multiple requests. It handles the transient itself, so just looking up if a request has failed previously.
                if ( $allow_remote_request ){ //If we are actively allowed to make the request to check if the endpoint is actually available
                    //Combine default args with passed args. Args docs: https://developer.wordpress.org/reference/classes/WP_Http/request/
                    $all_args = array_merge(array(
                        'redirection' => 5, //Follow 5 redirects before quitting
                    ), $args);
    
                    //Only get the head data for slight speed improvement.
                    $response = wp_remote_head($url, $all_args);
                    if ( !is_wp_error($response) && $response['response']['code'] === 200 ){ //If the remote request was successful
                        set_transient('nebula_site_available_' . $hostname, 'Available', MINUTE_IN_SECONDS*20); //20 minute expiration
                        $this->timer($timer_name, 'end');
                        return true;
                    }
                }
    
                if ( !$allow_remote_request ){ //Otherwise, do not actively check and just report that the site was not reportedly down prior
                    $this->timer($timer_name, 'end');
                    return true; //Resource may not actually be available, but was asked specifically not to check.
                }
    
                //Finally, if none of the previous checks were true, the site must be unavailable
                set_transient('nebula_site_available_' . $hostname, 'Unavailable', MINUTE_IN_SECONDS*10); //10 minute expiration
                $this->timer($timer_name, 'end');
                return false;
            }
    

    Override

    To override this PHP function, use this hook in your child theme or plugin ("my_custom" can be changed):

    PHP
    add_filter('pre_nebula_is_available', 'my_custom_is_available', 10, 5); //The last integer must be 1 more than the actual parameters
    function my_custom_is_available($null, $url, $allow_cache, $allow_remote_request, $args){ //$null is required, but can be ignored
        //Write your own code here
    
        return true; //Return true to prevent the original function from running afterwords
    }

    You can completely disable this PHP function with a single line actions:

    PHP
     add_filter('pre_nebula_is_available', '__return_false');