$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>rest api - Remove caching from wp_remote_get calls from custom plugin|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

rest api - Remove caching from wp_remote_get calls from custom plugin

matteradmin8PV0评论

I wrote a plugin to hit an API and display results on a page. When I was testing, every time I hit "preview", the plugin would hit the API and retrieve the most recent data. Now that the plugin is live, when I navigate to the live page, no calls are being made to the API.

Through research I believe this is a caching issue, since we want real time data, we would like that every time a user navigates to the page, the plugin fires off to the API and the most recent values are returned.

Here is a snippet of my code:

function get_count(){

//get response from api
$request = wp_remote_get('');

if(is_wp_error($request)){
    return false;
}

//get the body from the response
$body= json_decode(wp_remote_retrieve_body($request));

//parse the body and get the count attribute
$statistic=($body->payload->count);

return '<div id="value" class="number">'. $statistic . '</div>';
}

add_shortcode('real_time_count','get_count');

How can I make this execute every time a user navigates to a page that has this shortcode?

I wrote a plugin to hit an API and display results on a page. When I was testing, every time I hit "preview", the plugin would hit the API and retrieve the most recent data. Now that the plugin is live, when I navigate to the live page, no calls are being made to the API.

Through research I believe this is a caching issue, since we want real time data, we would like that every time a user navigates to the page, the plugin fires off to the API and the most recent values are returned.

Here is a snippet of my code:

function get_count(){

//get response from api
$request = wp_remote_get('https://myapi/count');

if(is_wp_error($request)){
    return false;
}

//get the body from the response
$body= json_decode(wp_remote_retrieve_body($request));

//parse the body and get the count attribute
$statistic=($body->payload->count);

return '<div id="value" class="number">'. $statistic . '</div>';
}

add_shortcode('real_time_count','get_count');

How can I make this execute every time a user navigates to a page that has this shortcode?

Share Improve this question edited Mar 1, 2019 at 18:33 rudtek 6,4035 gold badges30 silver badges52 bronze badges asked Mar 1, 2019 at 14:55 user2821694user2821694 211 silver badge2 bronze badges 3
  • 1 If you use curl instead of remote_get, do you have the same experience? – MikeNGarrett Commented Mar 1, 2019 at 15:09
  • @MikeNGarrett The question says that the request to the API isn't being made, not that there was anything wrong with the result of the request. This would happen if they had some sort of caching, which the question also mentions. – Jacob Peattie Commented Mar 1, 2019 at 15:45
  • Oh. Different question entirely. Sorry about that. – MikeNGarrett Commented Mar 1, 2019 at 16:14
Add a comment  | 

2 Answers 2

Reset to default 3

If you want to make sure the data bypasses any front-end caching, you should use AJAX to request the data and print it on the page.

What I'd suggest is keeping your shortcode, but using AJAX to update it but creating a REST API endpoint. To do this you would abstract away the API request into its own function, and then have the shortcode and API response both use that function:

/**
 * Function for retrieving the count from the API.
 */
function wpse_330377_get_count() {
    $request = wp_remote_get( 'https://myapi/count' );

    if( is_wp_error( $request ) ) {
        return false;
    }

    $body = json_decode( wp_remote_retrieve_body( $request ) );

    $statistic = $body->payload->count;

    return $statistic;
}

/**
 * Shortcode for outputting the count.
 */
function wpse_330377_count_shortcode() {
    $statistic = wpse_330377_get_count();

    return '<div id="value" class="number">'. $statistic . '</div>';
}
add_shortcode( 'real_time_count', 'wpse_330377_count_shortcode' );

/**
 * REST API endpoint for getting the count.
 */
function wpse_330377_register_rest_route() {
    register_rest_route( 
        'wpse_330377', 
        'count',
        [
            'method'   => 'GET',
            'callback' => 'wpse_330377_get_count'
        ]
    );
}
add_action( 'rest_api_init', 'wpse_330377_register_rest_route' );

Now you can use JavaScript to send a request to the new API endpoint, /wp-json/wpse_330377/count, which will give us the new value that we can use to update the #value div.

Create a JavaScript file like this, in your theme or plugin:

jQuery.get(
    {
        url: wpse330377.apiUrl,
        success: function( data ) {
            jQuery( '#value' ).html( data );
        }
    }
);

And then enqueue it and pass it the correct URL:

function wpse_330377_enqueue_script() {
    wp_enqueue_script( 'wpse_330377_count', 'URL TO SCRIPT GOES HERE', [ 'jquery' ], null, true );
    wp_localize_script(
        'wpse_330377_count',
        'wpse330377',
        [
            'apiUrl' => rest_url( 'wpse_330377/count' ),
        ]
    );
}
add_action( 'wp_enqueue_scripts', 'wpse_330377_enqueue_script' );

Just replace URL TO SCRIPT GOES HERE with the actual URL. Use get_theme_file_uri() to get the URL for a file in your theme, or plugins_url() if it's in a plugin.

PS: Note that I've used wpse_330377 as a prefix and namespace in many places. You should use a prefix like this to prevent conflicts with WordPress and other themes or plugins. Ideally it would be something specific to your project.

I missed the last part of your question :facepalm:

In this case, it depends on what your caching mechanism is on your site. Some plugins, like W3 Total Cache, allow you to mark sections of a page as non-cacheable. If this isn't an option, then Jacob's answer about using AJAX is probably the way to go. This way, you can request the data "fresh" every time.

Not what you're looking for below

You should check a couple of things. The only caching that might affect wp_remote_get would be on the response side of things, since WordPress does not cache anything it gets back in the WP_Http class's request method.

As Mike commented, do you get the same "empty" response using curl? Try this on the command line if you have curl available:

curl https://myapi/count

Does the response look the same as doing

curl https://myapi/count?foo=134134234234

?

If the responses differ, then your myapi server may be caching the response. If not, you need to figure out why the remote server is not sending back the expected response.

Debugging Further

If it's not caching, you should do something like this:

// In your wp-config.php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', WP_DEBUG );

In your function above:

if ( is_wp_error( $request ) ) {
    error_log( $request->get_error_message() );
}

Now, run your script, and then check the contents of /wp-content/debug.log to see if there are any errors related to your request.

If your certificate for myapi isn't "valid" (i.e. signed by a CA), you should look at the arg sslverify for wp_remote_get:

@type bool $sslverify Whether to verify SSL for the request. Default true.

Which can be modified like so:

wp_remote_get( 'https://myapi/count`, [ 'sslverify' => false ] );

If it is caching

You can use the current time to bust the cache of each request, like so:

$request = wp_remote_get( 'https://myapi/count?time=' . time() );
Post a comment

comment list (0)

  1. No comments so far