这里有两种选择,一种是 Wordpress,另一种是 SQL。
在我开始之前,您永远不应该对数据库名称进行硬编码,问题是,如果您将代码移动到具有不同数据库名称的另一个网站,则需要在所有硬编码查询中更改数据库名称,当您在您正在处理的网站上更改数据库名称时。如果您忘记了这一点,这会让您大吃一惊
您应该始终清理和验证输入数据,以确保可以安全地防止任何恶意代码注入您的网站。 SQL 注入很常见,许多黑客使用 SQL 注入来入侵网站
SQL
SQL 提供的控制较少,因为它的动态性较低。例如,如果您只需要获取某个词的计数,则需要直接更改查询,或者您需要实现某种过滤系统。
正如我所说,永远不要硬编码数据库名称,而是使用 wpdb 类来设置前缀。这将避免未来的问题。另外,正如我所说,您必须进行清理以避免 SQL 注入,在这种情况下,我们将使用 wpdb 类的 prepare 方法来进行清理并防止 SQL 注入。
这里是函数,我在这里和那里评论过它是有意义的:
function get_post_meta_key_count( $key = '', $value = '', $type = 'post', $status = 'publish' )
{
// Use $wpdb to avoid bugs and errors, do not hardcode db names
global $wpdb;
if( empty( $key ) )
return;
// Set the default WHERE clause where we return the count of the key regardless of value
$where = $wpdb->prepare(
"
pm.meta_key = '%s'
AND p.post_type = '%s'
AND p.post_status = '%s'
",
$key,
$type,
$status
);
// If a value is specified, add that to the WHERE clause
if ( $value ) {
$where .= $wpdb->prepare(
"
AND pm.meta_value = '%s'
",
$value
);
}
// Query the db to return the post count according to key and value if value is set
$count = $wpdb->get_var(
"
SELECT count(DISTINCT pm.post_id)
FROM {$wpdb->postmeta} pm
JOIN {$wpdb->posts} p ON (p.ID = pm.post_id)
WHERE {$where}
"
);
return $count;
}
我在这里所做的是,如果您需要获取特定元键的特定元值的计数,我已经设置了一个参数。
用法
您现在可以使用如下功能:
echo get_post_meta_key_count( 'my_key' ); 用于 meta_key 的帖子计数 my_key 用于默认帖子类型 post 并且仅发布帖子
echo get_post_meta_key_count( 'my_key', '', 'custom_post_type', 'trash' ); 用于 meta_key 的帖子计数 my_key 用于自定义帖子类型 custom_post_type 并且仅垃圾帖子
echo get_post_meta_key_count( 'my_key', 'my_value' ); 用于meta_key my_key 的帖子计数和meta_value、my_value 用于默认帖子类型post 并且仅发布帖子
WP_Query
如果您正在寻找一种内置方式来执行此操作(这应该始终是您的首选),您可以使用 WP_Query 类来执行此操作。
使用WP_Query 的问题在于,如果使用不当,可能会非常昂贵。许多人因此而避免WP_Query,或者在不知不觉中运行非常昂贵且不必要的查询。因此,我们将寻找一种方法使其与自定义 SQL 查询一样快。
WP_Query 上述自定义 SQL 查询的真正优势在于,您可以通过简单地传入所需的参数来调整查询,WP_Query 将始终负责根据传递参数。
让我们看看优化 WP_Query 以便只返回帖子计数
-
首先,我们将只查询一个帖子。 WP_Query,默认情况下,无论查询多少帖子(1、100 或所有帖子),WP_Query 都会继续寻找所有与查询匹配的帖子,即使它已经找到并返回了查询的帖子数量。原因是分页。为了正确计算分页,WP_Query 需要知道有多少帖子与查询匹配。
所以WP_Query 在返回查询的帖子数量后继续查看数据库,以计算与查询匹配的所有帖子。这个帖子计数存储在查询的$found_posts 属性中,并且正是这个数字与posts_per_page 一起使用,用于计算将有多少页。
这不适用于get_posts,尽管get_posts 使用WP_Query。 get_posts 将 'no_found_rows' => true 传递给 WP_Query,一旦找到查询的帖子数量,就会中断查询。这在法律上破坏了分页,这就是为什么 get_posts 正确分页是如此令人头疼的原因
其次,我们只会查询我们需要查询的单个帖子的ID,而不是完整的WP_Post对象。这节省了查询时间。
让我们看看这个函数:
function get_post_meta_key_count( $key = '', $value = '', $args = [] )
{
// If the $key value is empty, bail
if( empty( $key ) )
return;
// Set the defaults and override any value set for the specific default
$args['posts_per_page'] = 1;
$args['fields'] = 'ids';
if ( $value ) {
$args['meta_query'][] = [
'key' => $key,
'value' => $value
];
} else {
$args['meta_query'][] = [
'key' => $key,
];
}
$q = new WP_Query( $args );
// Return the post count
return $q->found_posts;
}
用法
WP_Query,默认使用post帖子类型和publish作为帖子状态,所以我们不需要为正常发布的帖子设置这个。我在这里包含了第三个参数$args,该参数接受与WP_Query 类相同的参数,因为这些参数都直接传递给WP_Query。因此,您可以在此处添加任何参数以从特定元键或值中获取计数
echo get_post_meta_key_count( 'my_key' ); 用于meta_key 的帖子计数my_key 用于默认帖子类型post 并且仅发布帖子
echo get_post_meta_key_count( 'my_key', 'my_value' ); 用于meta_key my_key 的帖子计数和meta_value,my_value 用于默认帖子类型post 并且仅发布帖子
echo get_post_meta_key_count( 'my_key', 'my_value', ['post_type'=>'cpt', 'cat'=>1] ); 用于meta_key my_key 的帖子计数和meta_value、my_value 用于自定义帖子类型cpt 并且仅发布来自类别ID 1 的帖子
meta_key 的性能测试,包含 24 个帖子
如您所见,性能存在细微差别,因此WP_Query 方法很容易成为最佳选择,因为它更具动态性,尽管速度稍慢