tl;dr: 为查询构建价格合理的唯一标识符是可能的,但这毫无用处。
如果要查找查询对象的唯一标识符,则可以使用spl_object_hash
, 但IMHO非常无用:它是不可预测的,而且即使查询变量相同,但设置在两个不同的查询对象上,您也会得到不同的id。使用它的唯一原因是可以获得这样的统计信息:“在此请求期间XX不同WP_Query
对象已实例化。“”
如果您将注意力放在查询变量上,可能是因为您正在查找标识查询结果的id,即当您可以从两个不同的查询对象获得相同的id时,两个查询的结果应该相同。
在这种情况下,我要给你一个不好的惊喜:这永远不会发生,因为无论你使用什么技术,如果你基于查询变量构建你的查询id,你都不会考虑\'posts_*\'
过滤器(\'posts\\u where\',\'posts\\u join\'等,它们是19 IIRC)。
概念验证:
$query1 = new WP_Query( \'post_type=post\' );
add_filter( \'posts_where\', function() { return \' AND 1 = 0\'; } );
$query2 = new WP_Query( \'post_type=post\' );
$query1
和
$query2
相同,因此基于查询变量返回唯一id的虚拟回调将为这两个查询返回相同的id,但第一个查询返回所有已发布的帖子,第二个查询不返回任何内容。
这就是为什么查询变量不是构建唯一查询id的良好起点。
如果重要的是查询结果,那么应该集中精力查询sql请求:当请求相同时,结果也会相同,另外请求是一个字符串,所以很容易散列。
当请求已完全构建,但尚未执行时,范围的良好候选挂钩应该是一个,\'split_the_query\' 过滤器挂钩应完好。
// prepare our ids storage
add_action( \'init\', function() {
global $query_ids;
$query_ids = array();
});
// use the filter to build and store the id
add_filter( \'split_the_query\', function( $split_the_query, $query ) {
$hash = md5( $query->request );
$hash .= $split_the_query ? \'_split\' : \'\';
global $query_ids;
if ( ! in_array( $hash, $query_ids, TRUE ) ) {
$query_ids[] = $hash; // store hash if not already stored
}
return $split_the_query; // return $split_the_query as is
}, PHP_INT_MAX, 2 );
现在,我们有了一种构建唯一查询标识符的方法:当我们可以从两个查询中获得相同的标识符时,那么这两个查询的结果是相同的。
但是我们能做什么呢?可能是这样的统计数据:
add_action(\'shutdown\', function() {
global $query_ids;
echo count( $query_ids ) . " different WP_Query requests were performed.";
});
我找不到这样的统计数据有什么用处,但也许有人可以。
我知道您正在考虑使用查询标识符来缓存查询,并且在id相同时不要触发数据库请求,这是一个好主意,但是。。。你不能。
问题是,当WordPress构建了请求,然后立即运行它,这样您就没有机会短路它!
或者更好,一旦WordPress使用$wpdb->get_results
要执行查询,请执行一次$wpdb
是一个全局变量,有可能用一个能够缓存的修改过的wpdb类替换该对象,这是一个好主意,但在这种情况下,一旦所有缓存都发生在$wpdb
基于在那里运行的sql请求。
实质上,问题是WordPress面临两大问题:WP_Query
逻辑(以及其他关于WP_Query
混乱代码):
构建过程的查询和运行过程的查询是不可分离的WP_Query::get_posts()
方法。在这两个问题没有解决之前,无法阻止运行sql查询。如何为查询创建唯一id只能用于偏心统计。。。