钩子文档

posts_clauses

💡 云策文档标注

概述

posts_clauses 是一个 WordPress 过滤器,用于一次性修改查询的所有子句,如 WHERE、GROUP BY、JOIN 等,适用于需要批量调整查询或避免其他插件覆盖的场景。

关键要点

  • 过滤器参数:$clauses 是一个关联数组,包含查询的各个子句(如 where、groupby、join 等),$query 是 WP_Query 实例(引用传递)。
  • 使用时机:在查询执行前运行,是多个子句特定过滤器(如 posts_where_paged)的汇总,适合需要同时修改多个查询部分的情况。
  • 注意事项:如果仅修改特定子句,建议使用对应的子句特定过滤器;对于缓存插件开发,应使用 posts_clauses_request 过滤器以确保在常规插件之后运行。

代码示例

function intercept_query_clauses( $pieces ) {
    // 仅管理员可查看查询调试信息
    if ( current_user_can( 'manage_options' ) ) {
        $dump = var_export( $pieces, true );
        echo "<pre id='post-clauses-dump'>{$dump}</pre>";
    }
    // 修改查询子句,例如:$pieces['where'] = '自定义条件';
    return $pieces;
}
add_filter( 'posts_clauses', 'intercept_query_clauses', 20, 1 );

注意事项

  • 在修改查询子句时,应使用 $wpdb 方法和属性(如 $wpdb->prepare())来防止 SQL 注入攻击和处理表前缀变化。
  • 示例输出展示了在管理后台“所有文章”页面中查询子句的典型结构,包括 where、orderby、limits 等字段。

📄 原文内容

Filters all query clauses at once, for convenience.

Description

Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT, fields (SELECT), and LIMIT clauses.

Parameters

$clausesstring[]
Associative array of the clauses for the query.

  • where string
    The WHERE clause of the query.
  • groupby string
    The GROUP BY clause of the query.
  • join string
    The JOIN clause of the query.
  • orderby string
    The ORDER BY clause of the query.
  • distinct string
    The DISTINCT clause of the query.
  • fields string
    The SELECT clause of the query.
  • limits string
    The LIMIT clause of the query.

$queryWP_Query
The WP_Query instance (passed by reference).

More Information

The posts_clauses filter runs before the query gets executed and is essentially the sum of all filters that run immediately before it. So it should be used if you don’t intend to let another plugin override it, or if you need to alter several different parts of the query at once. If you’re only modifying a particular clause, you should probably use one of these clause-specific filters:

* posts_where_paged
* posts_groupby
* posts_join_paged
* posts_orderby
* posts_distinct
* post_limits
* posts_fields

Note: If you’re working on a caching plugin, use the posts_clauses_request filter instead. It’s basically the same filter, but it runs later (and after posts_selection), specifically so that “regular” plugins can execute their filters before your caching plugin does anything.

Source

$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );

Changelog

Version Description
3.1.0 Introduced.

User Contributed Notes

  1. Skip to note 2 content

    Example migrated from Codex:

    In the following example, you can see how you can inspect the current query.

    #post-clauses-dump { display: block; background-color: #777; color: #fff; white-space: pre-line; }</style>';
    	// >>>> Inspect & Debug the Query 
    	// NEVER EVER show this to anyone other than an admin user - unless you're in your local installation
    	if ( current_user_can( 'manage_options' ) )
    	{
    		$dump = var_export( $pieces, true );
    		echo "< PRE id='post-clauses-dump'>{$dump}</pre>";
    	}
    
    	return $pieces;
    }
    add_filter( 'posts_clauses', 'intercept_query_clauses', 20, 1 );

    If you need to alter anything, simply set the $pieces['whatever_part'] string to what you need. Be sure to use appropriate $wpdb properties and methods (e.g. $wpdb->prefix, $wpdb->prepare()) in your SQL to prevent injection attacks, handle table prefix variations, and so forth.

    This would be the output on the Admin “All Posts” example.com/wp-admin/edit.php screen:

    array (
    	'where' => ' AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'private')',
    	'groupby' => '',
    	'join' => '',
    	'orderby' => 'wp_posts.post_date DESC',
    	'distinct' => '',
    	'fields' => 'wp_posts.*',
    	'limits' => 'LIMIT 0, 20',
    )