Search code examples
phpjsonwordpresscachingcloudflare

Purging Cloudflare cache through their API in php


I came across this problem with a friend's website. It's a Wordpress installation with several plugins. One of those plugins is used to update several images (gathering them from remote locations and storing them locally to save bandwidth). But when running the plugin, the website seemingly refused to display the updated images and continuously gave me the old version which were definetly no longer present on the server.

Browser cache was ruled out quickly as the cause. Wordpress can be a bit tricky, so I checked all other plugins, drop-ins and whether any form of object cache was active. After also ruling that out, it came to me that the hosting provider must be the issue. I didn't know and had to find out that they use Cloudflare as DNS provider to have a valid SSL certificate for their website. However by default Cloudflare also comes with caching which can be quite aggressive.

Since they liked the caching and wanted to keep it turned on, I told my friend to manually purge the cache at Cloudflare. Ta-Da - the updated images were showing just as they should.

So in order to avoid the process of logging into Cloudflare everytime the plugin is called, I was looking for a way to use their API to solve this in a convenient way. I needed some php-code (to integrate into the Wordpress-Plugin)...


Solution

  • I wrote a small and surely improveable php-script which serves exactly this purpose. It uses the given credentials (user-email and API key) to connect to Cloudflare's API. To retrieve the API key:

    1. Login to the Cloudflare account.

    2. Go to My Profile.

    3. Scroll down to API Keys and locate Global API Key.

    4. Click API Key to see your API identifier.

    In the first step the script queries the so called Zone-ID which is a unique identifier for the domain you want to control. Since Cloudflare to date gives no option to view this ID in their backend it can only be obtained through an API request.

    In the second step we again connect to Cloudflare's API, this time instructing to purge the entire cache for that Zone.

    Here's my solution (I put this on the bottom of my plugin updater-script, to run after everything else has finished):

    <?php
    
        //Credentials for Cloudflare
        $cust_email = ''; //[email protected]
        $cust_xauth = ''; //retrieved from the backend after loggin in
        $cust_domain = ''; //domain.tld, the domain you want to control
    
        if($cust_email == "" || $cust_xauth == "" || $cust_domain == "") return;
    
        //Get the Zone-ID from Cloudflare since they don't provide that in the Backend
        $ch_query = curl_init();
        curl_setopt($ch_query, CURLOPT_URL, "https://api.cloudflare.com/client/v4/zones?name=".$cust_domain."&status=active&page=1&per_page=5&order=status&direction=desc&match=all");
        curl_setopt($ch_query, CURLOPT_RETURNTRANSFER, 1);
        $qheaders = array(
            'X-Auth-Email: '.$cust_email.'',
            'X-Auth-Key: '.$cust_xauth.'',
            'Content-Type: application/json'
        );
        curl_setopt($ch_query, CURLOPT_HTTPHEADER, $qheaders);
        $qresult = json_decode(curl_exec($ch_query),true);
        curl_close($ch_query);
    
        $cust_zone = $qresult['result'][0]['id']; 
    
        //Purge the entire cache via API
        $ch_purge = curl_init();
        curl_setopt($ch_purge, CURLOPT_URL, "https://api.cloudflare.com/client/v4/zones/".$cust_zone."/purge_cache");
        curl_setopt($ch_purge, CURLOPT_CUSTOMREQUEST, "DELETE");
        curl_setopt($ch_purge, CURLOPT_RETURNTRANSFER, 1);
        $headers = [
            'X-Auth-Email: '.$cust_email,
            'X-Auth-Key: '.$cust_xauth,
            'Content-Type: application/json'
        ];
        $data = json_encode(array("purge_everything" => true));
        curl_setopt($ch_purge, CURLOPT_POST, true);
        curl_setopt($ch_purge, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch_purge, CURLOPT_HTTPHEADER, $headers);
    
        $result = json_decode(curl_exec($ch_purge),true);
        curl_close($ch_purge);
    
        //Tell the user if it worked
        if($result['success']==1) echo "Cloudflare Cache successfully purged! Changes should be visible right away.<br>If not try clearing your Browser Cache by pressing \"Ctrl+F5\"";
        else echo "Error purging Cloudflare Cache. Please log into Cloudflare and purge manually!";
    
    ?>