wp_count_posts()
云策文档标注
概述
wp_count_posts() 函数用于高效统计指定文章类型的文章数量,并考虑用户权限(如可读性)。它返回一个包含各状态文章数量的对象,适用于 WordPress 2.5 及以上版本,替代了 get_posts() 等开销较大的方法。
关键要点
- 函数返回一个 stdClass 对象,属性为文章状态(如 publish、draft)及其对应数量
- 参数 $type 指定文章类型,默认为 'post';$perm 可选 'readable' 以检查用户读取私有文章的权限
- 使用缓存机制(wp_cache_get/set)提升性能,并应用 wp_count_posts 过滤器
- 内部根据权限条件优化 SQL 查询,利用数据库索引
- 相关函数包括 post_type_exists()、get_post_stati()、current_user_can() 等
代码示例
// 获取已发布文章数量
$count_posts = wp_count_posts();
if ( $count_posts ) {
$published_posts = $count_posts->publish;
}
// 仅 PHP5+ 的简写方式
$published_posts = wp_count_posts()->publish;
// 统计页面数量
$count_pages = wp_count_posts( 'page' );注意事项
- 如果文章类型不存在,函数返回空对象
- 默认情况下,$perm 参数为空,不检查权限;设为 'readable' 时,会根据当前用户能力调整私有文章统计
- 对象属性包括所有注册的文章状态,未出现的状态计为 0
原文内容
Counts number of posts of a post type and if user has permissions to view.
Description
This function provides an efficient method of finding the amount of post’s type a blog has. Another method is to count the amount of items in get_posts() , but that method has a lot of overhead with doing so. Therefore, when developing for 2.5+, use this function instead.
The $perm parameter checks for ‘readable’ value and if the user can read private posts, it will display that for the user that is signed in.
Parameters
$typestringoptional-
Post type to retrieve count. Default
'post'. $permstringoptional-
'readable'or empty. Default empty.
Source
function wp_count_posts( $type = 'post', $perm = '' ) {
global $wpdb;
if ( ! post_type_exists( $type ) ) {
return new stdClass();
}
$cache_key = _count_posts_cache_key( $type, $perm );
$counts = wp_cache_get( $cache_key, 'counts' );
if ( false !== $counts ) {
// We may have cached this before every status was registered.
foreach ( get_post_stati() as $status ) {
if ( ! isset( $counts->{$status} ) ) {
$counts->{$status} = 0;
}
}
/** This filter is documented in wp-includes/post.php */
return apply_filters( 'wp_count_posts', $counts, $type, $perm );
}
if (
'readable' === $perm &&
is_user_logged_in() &&
! current_user_can( get_post_type_object( $type )->cap->read_private_posts )
) {
// Optimized query uses subqueries which can leverage DB indexes for better performance. See #61097.
$query = "
SELECT post_status, COUNT(*) AS num_posts
FROM (
SELECT post_status
FROM {$wpdb->posts}
WHERE post_type = %s AND post_status != 'private'
UNION ALL
SELECT post_status
FROM {$wpdb->posts}
WHERE post_type = %s AND post_status = 'private' AND post_author = %d
) AS filtered_posts
";
$args = array( $type, $type, get_current_user_id() );
} else {
$query = "
SELECT post_status, COUNT(*) AS num_posts
FROM {$wpdb->posts}
WHERE post_type = %s
";
$args = array( $type );
}
$query .= ' GROUP BY post_status';
$results = (array) $wpdb->get_results(
$wpdb->prepare( $query, ...$args ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Placeholders are used in the string contained in the variable.
ARRAY_A
);
$counts = array_fill_keys( get_post_stati(), 0 );
foreach ( $results as $row ) {
$counts[ $row['post_status'] ] = $row['num_posts'];
}
$counts = (object) $counts;
wp_cache_set( $cache_key, $counts, 'counts' );
/**
* Filters the post counts by status for the current post type.
*
* @since 3.7.0
*
* @param stdClass $counts An object containing the current post_type's post
* counts by status.
* @param string $type Post type.
* @param string $perm The permission to determine if the posts are 'readable'
* by the current user.
*/
return apply_filters( 'wp_count_posts', $counts, $type, $perm );
}
Hooks
- apply_filters( ‘wp_count_posts’, stdClass $counts, string $type, string $perm )
-
Filters the post counts by status for the current post type.
Changelog
| Version | Description |
|---|---|
| 2.5.0 | Introduced. |
Skip to note 7 content
Codex
Get the Publish Status Post Count
To get the published status type, you would call the wp_count_posts() function and then access the ‘publish’ property.
$count_posts = wp_count_posts(); if ( $count_posts ) { $published_posts = $count_posts->publish; }If you are developing for PHP5 only, then you can use shorthand, if you only want to get one status. This will not work in PHP4 and if you want to maintain backwards compatibility, then you must use the above code.
Skip to note 8 content
Mike Ritter
This function returns an object whose properties you can access:
stdClass Object ( [publish] => 12 [future] => 0 [draft] => 0 [pending] => 0 [private] => 0 [trash] => 1 [auto-draft] => 1 [inherit] => 0 [request-pending] => 0 [request-confirmed] => 0 [request-failed] => 0 [request-completed] => 0 ) 1So, to find out if you have more than 1 post published try:
if( wp_count_posts()->publish > 1 ) : return true; else: return false; endif;Skip to note 9 content
Codex
Basic Example
The default usage returns a count of the posts that are published. This will be an object, you can var_dump() the contents to debug the output.
Skip to note 10 content
Codex
Count Drafts
Counting drafts is handled the same way as the publish status.
$count_posts = wp_count_posts(); if ( $count_posts ) { $draft_posts = $count_posts->draft; }Skip to note 11 content
Codex
Count Pages
Counting pages status types are done in the same way as posts and make use of the first parameter. Finding the number of posts for the post status is done the same way as for posts.
$count_pages = wp_count_posts( $post_type = 'page' );Skip to note 12 content
Codex
Other Uses
The wp_count_posts() can be used to find the number for post statuses of any post type. This includes attachments or any post type added in the future, either by a plugin or part of the WordPress Core.