我之前在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中工作(不包含在函数中)或解决方法?
或许是一些全新的开箱即用的想法?
答案 0 :(得分:2)
所有这些Ajax请求导致几个数据库查询相同 数据。因此,保存一些数据库查询的明显想法是通过 数据到全局变量如下:
$_GLOBALS['user_data'] = get_user_by('login', get_query_var('user_login'));
然后在Ajax回调中使用相同的内容。
您的应用程序收到的每个请求,AJAX或其他请求完全独立存在:处理请求的代码不会共享它们之间的任何状态(除了持久保存到数据库之外)。您在一个请求中定义的全局(或常量,或属性,变量或任何内容)将永远不会对后续请求可用,除非您将其存储在某个位置。
有许多方法可以减少这些请求创建的查询数量。一种方法是在页面加载时检索所需的用户数据并将其传递给后续请求。 E.g:
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); ?>;
另一个选择是确保通过Wordpress,MySQL或其他一些缓存层缓存get_user_by
结果。这样,代码调用方法的次数并不特别重要。
通常,如果您的许多端点都在共享功能,那么您可能会重构某些代码。