WP_Comment_Query
Core class for querying comments from the database.
Since: 3.1.0
Source: wp-includes/class-wp-comment-query.php
Overview
WP_Comment_Query retrieves comments based on specified criteria. It supports filtering, pagination, meta queries, date queries, and hierarchical comment retrieval.
Basic Usage
// Simple query
$query = new WP_Comment_Query( array(
'post_id' => 42,
'status' => 'approve',
) );
$comments = $query->comments;
// Using get_comments() wrapper
$comments = get_comments( array(
'post_id' => 42,
'status' => 'approve',
) );
Class Properties
| Property | Type | Description |
|---|---|---|
$request |
string | The SQL query string |
$meta_query |
WP_Meta_Query | Meta query instance |
$date_query |
WP_Date_Query | Date query instance |
$query_vars |
array | Query variables set by user |
$query_var_defaults |
array | Default values for query vars |
$comments |
int[] | WP_Comment[] |
$found_comments |
int | Total found comments |
$max_num_pages |
int | Number of pages |
Query Variables
Comment Selection
| Parameter | Type | Default | Description |
|---|---|---|---|
comment__in |
int[] | ” | Include specific comment IDs |
comment__not_in |
int[] | ” | Exclude specific comment IDs |
parent |
int | ” | Parent comment ID |
parent__in |
int[] | ” | Parent IDs to include children for |
parent__not_in |
int[] | ” | Parent IDs to exclude children for |
Example:
// Get specific comments
$comments = get_comments( array(
'comment__in' => array( 10, 20, 30 ),
) );
// Get replies to specific comment
$replies = get_comments( array(
'parent' => 123,
) );
// Get replies to multiple parents
$replies = get_comments( array(
'parent__in' => array( 10, 20, 30 ),
) );
Post Filtering
| Parameter | Type | Default | Description |
|---|---|---|---|
post_id |
int | 0 | Limit to specific post ID |
post__in |
int[] | ” | Include comments from these posts |
post__not_in |
int[] | ” | Exclude comments from these posts |
post_author |
int | ” | Post author ID |
post_author__in |
int[] | ” | Post author IDs to include |
post_author__not_in |
int[] | ” | Post author IDs to exclude |
post_status |
string | string[] | ” |
post_type |
string | string[] | ” |
post_name |
string | ” | Post slug |
post_parent |
int | ” | Post parent ID |
Example:
// Comments on specific post
$comments = get_comments( array(
'post_id' => 42,
) );
// Comments on posts by author
$comments = get_comments( array(
'post_author' => 5,
) );
// Comments on published posts only
$comments = get_comments( array(
'post_status' => 'publish',
) );
// Comments on specific post type
$comments = get_comments( array(
'post_type' => 'product',
) );
Author Filtering
| Parameter | Type | Default | Description |
|---|---|---|---|
author_email |
string | ” | Comment author email |
author_url |
string | ” | Comment author URL |
author__in |
int[] | ” | Registered user IDs to include |
author__not_in |
int[] | ” | Registered user IDs to exclude |
user_id |
int | int[] | ” |
include_unapproved |
array | ” | IDs/emails whose unapproved comments to include |
Example:
// Comments by email
$comments = get_comments( array(
'author_email' => '[email protected]',
) );
// Comments by registered users
$comments = get_comments( array(
'author__in' => array( 1, 2, 3 ),
) );
// Include unapproved comments for current user
$comments = get_comments( array(
'post_id' => 42,
'include_unapproved' => array( get_current_user_id() ),
) );
Status Filtering
| Parameter | Type | Default | Description |
|---|---|---|---|
status |
string | array | ‘all’ |
Status Values:
'approve'or'1'– Approved comments'hold'or'0'– Pending comments'spam'– Spam comments'trash'– Trashed comments'all'or''– Approved and pending (excludes spam/trash)'any'– All statuses including spam/trash
Example:
// Approved only
$approved = get_comments( array(
'status' => 'approve',
) );
// Pending moderation
$pending = get_comments( array(
'status' => 'hold',
) );
// Multiple statuses
$comments = get_comments( array(
'status' => array( 'approve', 'hold' ),
) );
Type Filtering
| Parameter | Type | Default | Description |
|---|---|---|---|
type |
string | string[] | ” |
type__in |
string[] | ” | Types to include |
type__not_in |
string[] | ” | Types to exclude |
Type Values:
'comment'– Regular comments (includes empty type for BC)'pingback'– Pingback notifications'trackback'– Trackback notifications'pings'– Both pingback and trackback'all'or''– All types'note'– Internal notes (excluded by default since 6.9.0)
Example:
// Regular comments only
$comments = get_comments( array(
'type' => 'comment',
) );
// Pingbacks and trackbacks
$pings = get_comments( array(
'type' => 'pings',
) );
// Exclude pingbacks
$comments = get_comments( array(
'type__not_in' => array( 'pingback', 'trackback' ),
) );
// Include notes (normally excluded)
$notes = get_comments( array(
'type' => 'note',
) );
Ordering
| Parameter | Type | Default | Description |
|---|---|---|---|
orderby |
string | array | ‘comment_date_gmt’ |
order |
string | ‘DESC’ | Order direction: ‘ASC’ or ‘DESC’ |
Orderby Values:
'comment_agent'– Browser user agent'comment_approved'– Approval status'comment_author'– Author name'comment_author_email'– Author email'comment_author_IP'– Author IP'comment_author_url'– Author URL'comment_content'– Comment content'comment_date'– Local date'comment_date_gmt'– GMT date (default)'comment_ID'– Comment ID'comment_karma'– Karma score'comment_parent'– Parent ID'comment_post_ID'– Post ID'comment_type'– Comment type'user_id'– User ID'comment__in'– Match order ofcomment__inarray'meta_value'– Meta value (requiresmeta_key)'meta_value_num'– Numeric meta value'none',false, orarray()– Disable ordering
Example:
// Oldest first
$comments = get_comments( array(
'orderby' => 'comment_date',
'order' => 'ASC',
) );
// By karma, then date
$comments = get_comments( array(
'orderby' => array(
'comment_karma' => 'DESC',
'comment_date' => 'ASC',
),
) );
// By meta value
$comments = get_comments( array(
'meta_key' => 'rating',
'orderby' => 'meta_value_num',
'order' => 'DESC',
) );
// Match specific order
$comments = get_comments( array(
'comment__in' => array( 5, 2, 8, 1 ),
'orderby' => 'comment__in',
) );
Pagination
| Parameter | Type | Default | Description |
|---|---|---|---|
number |
int | ” | Maximum comments to return |
offset |
int | 0 | Number of comments to skip |
paged |
int | 1 | Page number (used with number) |
no_found_rows |
bool | true | Skip counting total rows |
Example:
// First 10 comments
$comments = get_comments( array(
'number' => 10,
) );
// Page 2, 10 per page
$comments = get_comments( array(
'number' => 10,
'paged' => 2,
) );
// Skip first 20, get next 10
$comments = get_comments( array(
'number' => 10,
'offset' => 20,
) );
// Get total count for pagination
$query = new WP_Comment_Query( array(
'post_id' => 42,
'number' => 10,
'no_found_rows' => false,
) );
echo "Page 1 of " . $query->max_num_pages;
Hierarchical/Threading
| Parameter | Type | Default | Description |
|---|---|---|---|
hierarchical |
bool | string | false |
Values:
false– Don’t include descendants'threaded'– Tree structure with children inWP_Comment::$children'flat'– Flat array including all descendants
Example:
// Threaded comments with children populated
$comments = get_comments( array(
'post_id' => 42,
'parent' => 0,
'hierarchical' => 'threaded',
) );
foreach ( $comments as $comment ) {
display_comment( $comment );
foreach ( $comment->get_children() as $reply ) {
display_reply( $reply );
}
}
// Flat list of all comments including replies
$comments = get_comments( array(
'post_id' => 42,
'hierarchical' => 'flat',
) );
Meta Query
| Parameter | Type | Default | Description |
|---|---|---|---|
meta_key |
string | string[] | ” |
meta_value |
string | string[] | ” |
meta_compare |
string | ‘=’ | Comparison operator |
meta_compare_key |
string | ‘=’ | Key comparison operator |
meta_type |
string | ‘CHAR’ | Value cast type |
meta_type_key |
string | ” | Key cast type |
meta_query |
array | ” | Complex meta query |
Example:
// Simple meta filter
$comments = get_comments( array(
'meta_key' => 'rating',
'meta_value' => 5,
) );
// Complex meta query
$comments = get_comments( array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'rating',
'value' => 4,
'compare' => '>=',
'type' => 'NUMERIC',
),
array(
'key' => 'verified',
'value' => 'yes',
),
),
) );
Date Query
| Parameter | Type | Default | Description |
|---|---|---|---|
date_query |
array | null | Date query clauses |
Example:
// Comments from last 30 days
$comments = get_comments( array(
'date_query' => array(
array(
'after' => '30 days ago',
),
),
) );
// Comments from specific date range
$comments = get_comments( array(
'date_query' => array(
array(
'after' => 'January 1, 2024',
'before' => 'March 31, 2024',
'inclusive' => true,
),
),
) );
Search
| Parameter | Type | Default | Description |
|---|---|---|---|
search |
string | ” | Search term |
Searches: comment_author, comment_author_email, comment_author_url, comment_author_IP, comment_content
Example:
$comments = get_comments( array(
'search' => 'wordpress',
) );
Other Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
karma |
int | ” | Specific karma score |
fields |
string | ” | ‘ids’ for IDs only, empty for full objects |
count |
bool | false | Return count instead of comments |
cache_domain |
string | ‘core’ | Cache key namespace |
update_comment_meta_cache |
bool | true | Prime meta cache |
update_comment_post_cache |
bool | false | Prime post cache |
Example:
// Get IDs only
$ids = get_comments( array(
'post_id' => 42,
'fields' => 'ids',
) );
// Count comments
$count = get_comments( array(
'post_id' => 42,
'count' => true,
) );
Methods
__construct()
Sets up the query.
public function __construct( $query = '' )
query()
Executes the query.
public function query( $query ): array|int
get_comments()
Internal method that retrieves comments.
public function get_comments(): int|int[]|WP_Comment[]
parse_query()
Parses query arguments.
public function parse_query( $query = '' )
SQL Clauses Filter
The comments_clauses filter allows modifying the SQL query:
add_filter( 'comments_clauses', function( $clauses, $query ) {
// $clauses = array(
// 'fields' => 'SELECT ...',
// 'join' => 'JOIN ...',
// 'where' => 'WHERE ...',
// 'orderby' => 'ORDER BY ...',
// 'limits' => 'LIMIT ...',
// 'groupby' => 'GROUP BY ...',
// );
return $clauses;
}, 10, 2 );
Performance Tips
- Use
no_found_rows(default true) when you don’t need pagination counts - Use
fields => 'ids'when you only need IDs - Set
update_comment_meta_cache => falseif you won’t access meta - Use
update_comment_post_cache => trueif accessing post properties
// Optimized query for counting
$count = get_comments( array(
'post_id' => 42,
'count' => true,
'update_comment_meta_cache' => false,
) );
Complete Example
// Get paginated, threaded comments for a post
$query = new WP_Comment_Query( array(
'post_id' => get_the_ID(),
'status' => 'approve',
'parent' => 0,
'number' => get_option( 'comments_per_page' ),
'paged' => get_query_var( 'cpage' ) ?: 1,
'no_found_rows' => false,
'hierarchical' => 'threaded',
'update_comment_post_cache' => false,
'include_unapproved' => is_user_logged_in()
? array( get_current_user_id() )
: array(),
) );
$comments = $query->comments;
$total_pages = $query->max_num_pages;
$total_comments = $query->found_comments;