【问题标题】:Make Wordpress Ajax calls work with global variables to reduce database queries使 Wordpress Ajax 调用与全局变量一起使用以减少数据库查询
【发布时间】:2012-03-29 22:41:01
【问题描述】:

我早些时候在 wordpress.stackexchange.com 上发布了这个。然而,始终没有得到答复。因此,在这里碰碰运气。

我在此详细说明我需要什么以及我为此问题所做的工作。我愿意接受围绕我所做的任何可行的解决方案或新的建议。

我需要使用通过以下方式检索到的用户数据:

$user_data = get_user_by('login', get_query_var('user_login'));

上面的代码使用 URL 中作为 query_var 传递的用户名。到这里为止一切正常。

我在单页加载的几个 Ajax 回调(由 admin-ajax.php 处理)中使用了上述代码。因为,该站点被定位为高容量站点。所有这些 Ajax 请求都会导致对相同数据的多个数据库查询。因此,保存一些数据库查询的明显想法是将数据传递给如下全局变量:

$_GLOBALS['user_data'] = get_user_by('login', get_query_var('user_login'));

然后在 Ajax 回调中使用相同的方法。这里有问题。 Ajax 回调函数都看不到全局 $user_data 变量。在你问之前,是的,我也声明了全局内部回调。

所以,显而易见的答案是:为什么不使用 wp_localize_script 并通过 javascript 将 $user_data 传递给 Ajax 回调,如下所示:

在 PHP 中:

wp_localize_script('jquery', 'ajaxVars', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'user_data' => $user_data));

在 Javascript 中:

        jQuery.ajax({
        url: ajaxVars.ajaxurl,   
        type:'POST',
        async: false,
        cache: false,
        timeout: 10000,
        data: 'action=ajax_callback&user_data=' + ajaxVars.user_data,
        success: function(value) {
            alert(value);
        },
        error: function() {
            alert(error);
        }
    });

但是,这提出了两个问题:

get_user_by('login', get_query_var('user_login')); 返回的对象可以由wp_localize_script() 处理吗?

如果上述问题的答案是肯定的,那么它不会构成安全威胁,因为该对象将包含敏感的用户信息?

为了克服全局变量对 Ajax 回调不可用的问题,我直接在 functions.php 中声明了它(没有将它包装在函数中)。但是,get_query_var('user_login') 直接在functions.php 中使用时不会返回任何数据,这使这个徒劳的练习(您必须将其添加到函数中并通过操作调用它)。

所以,问题仍然存在:如何停止为每个 Ajax 请求发出 $user_data = get_user_by('login', get_query_var('user_login')); 调用?或者有没有办法让get_query_var('user_login') 直接在functions.php 中工作(而不将其包装在函数中)或解决方法?

或者也许是一些全新的开箱即用的想法?

【问题讨论】:

    标签: ajax wordpress


    【解决方案1】:

    所有这些 Ajax 请求都会导致多个数据库查询相同 数据。所以保存一些数据库查询的明显想法是通过 数据到一个全局变量,如下所示:

    $_GLOBALS['user_data'] = get_user_by('login', get_query_var('user_login'));
    

    然后在 Ajax 回调中使用相同的方法。

    您的应用程序接收到的每个请求,无论是 AJAX 还是其他方式,都完全独立存在:处理请求的代码不会在它们之间共享任何状态(除了持久化到数据库的任何状态)。您在一个请求中定义的全局(或常量、属性、变量或任何东西)将永远无法用于后续请求,除非您将其存储在某处。

    有多种方法可以减少这些请求创建的查询数量。一种是在页面加载时检索所需的用户数据并将其传递给后续请求。例如:

    var user = 'someUser';
    
    $.get('user-data.php?user=' + user, function(user_data) {
        $.ajax('some-endpoint.php', {
                 type: 'POST',
                 data: { user: user_data },
                 success: function() { /* ... */ }
        });
        $.ajax('some-other-endpoint.php', {
                 type: 'POST',
                 data: { user: user_data },
                 success: function() { /* ... */ }
        });
    });
    

    或者,如果它是您正在使用的当前登录用户,您可以在初始页面加载时将其详细信息写入 JavaScript 对象以供以后使用。

    var userData = <?php get_currentuserinfo(); echo json_encode($current_user); ?>;
    

    另一种选择是确保 get_user_by 结果被 Wordpress、MySQL 或其他一些缓存层缓存。这样一来,您的代码调用该方法的次数并不特别重要。

    一般来说,如果您的许多端点都共享功能,您可能会重构其中的一些代码。

    【讨论】:

    • 感谢您的解释。我喜欢将用户数据写入 Javascript 对象并稍后检索它的想法。只是想知道这是否构成任何安全威胁?其次,我们可以使用 Transients API 之类的东西或其他东西让 Wordpress 缓存 get_user_by 结果吗?
    • 安全威胁在什么意义上?以一种或另一种方式,您正在检索该数据:无论您是在初始页面加载时呈现它还是将其作为对 AJAX 请求的响应来传递,都没有什么区别。您当然可以使用 Transients API 来缓存查询结果,但这可能只有在查询“昂贵”时才值得这样做。瞬态仍存储在数据库中,因此仍将执行查询来检索它们。
    • 这真的很有帮助。我想我会将用户数据作为 Javascript 对象传递
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2016-04-09
    • 2015-09-25
    相关资源
    最近更新 更多