从自定义插件的wp_emote_get调用中移除缓存

时间:2019-03-01 作者:user2821694

我编写了一个插件来点击API并在页面上显示结果。当我进行测试时,每次我点击“预览”,插件都会点击API并检索最新的数据。既然插件是活动的,当我导航到活动页面时,没有对API进行调用。

通过研究,我认为这是一个缓存问题,因为我们需要实时数据,我们希望每次用户导航到页面时,插件都会触发到API并返回最新的值。

以下是我的代码片段:

function get_count(){

//get response from api
$request = wp_remote_get(\'https://myapi.com/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\');
如何在用户每次导航到具有此短代码的页面时执行此操作?

2 个回复
SO网友:Jacob Peattie

如果要确保数据绕过任何前端缓存,应该使用AJAX请求数据并将其打印在页面上。

我建议保留您的短代码,但使用AJAX进行更新,但创建REST API端点。为此,您需要将API请求抽象为自己的函数,然后让shortcode和API响应都使用该函数:

/**
 * Function for retrieving the count from the API.
 */
function wpse_330377_get_count() {
    $request = wp_remote_get( \'https://myapi.com/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\' );
现在可以使用JavaScript向新的API端点发送请求,/wp-json/wpse_330377/count, 这将为我们提供新的值,我们可以使用它来更新#value 部门。

在主题或插件中创建如下JavaScript文件:

jQuery.get(
    {
        url: wpse330377.apiUrl,
        success: function( data ) {
            jQuery( \'#value\' ).html( data );
        }
    }
);
然后将其排队并传递正确的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\' );
只需更换URL TO SCRIPT GOES HERE 使用实际URL。使用get_theme_file_uri() 获取主题中文件的URL,或plugins_url() 如果它在插件中。

PS:注意,我使用了wpse_330377 在许多地方作为前缀和命名空间。您应该使用这样的前缀来防止与WordPress和其他主题或插件发生冲突。理想情况下,它将是特定于您的项目的东西。

SO网友:phatskat

我错过了你问题的最后一部分:facepalm:

在这种情况下,这取决于站点上的缓存机制。一些插件,如W3 Total Cache,允许您将页面的部分标记为不可缓存。如果这不是一个选项,那么Jacob关于使用AJAX的回答可能是一个不错的选择。这样,每次都可以请求“刷新”数据。

下面不是你想要的,你应该检查几件事。唯一可能影响wp_remote_get 因为WordPress不会缓存它在WP_Http 类别的request 方法

正如Mike评论的那样,您是否使用curl? 如果有,请在命令行中尝试此操作curl 可用:

curl https://myapi.com/count
回答是否与所做的相同

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

如果回答不同,那么myapi.com 服务器可能正在缓存响应。如果没有,则需要找出远程服务器没有发送回预期响应的原因。

进一步调试

如果不缓存,则应执行以下操作:

// In your wp-config.php
define( \'WP_DEBUG\', true );
define( \'WP_DEBUG_LOG\', WP_DEBUG );
在上述功能中:

if ( is_wp_error( $request ) ) {
    error_log( $request->get_error_message() );
}
现在,运行脚本,然后检查/wp-content/debug.log 查看是否有与您的请求相关的错误。

如果您的证书myapi.com 不是“有效”(即由CA签名),您应该查看argsslverify 对于wp_remote_get:

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

可以这样修改:

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

如果正在缓存,可以使用当前时间来中断每个请求的缓存,如下所示:

$request = wp_remote_get( \'https://myapi.com/count?time=\' . time() );

相关推荐

更改wp-admin/plugins.php上统计的插件数量

我已成功地使用从插件页面隐藏我的插件$wp_list_table 然而,顶部的分页仍然将插件列为“所有(3)”等。我成功地改变了$wp_list_table 的数组_pagination_args = total_items.但它仍然在页面顶部呈现插件-“全部(3)”。有什么办法可以解决这个问题吗?我找到了WP_Plugins_List_Table::prepare_items()具有全局$totals 变量,但我不确定我将如何改变这一点,在这个函数中$totals = array(); fore