在我的主页上,我有一个部分,我必须显示最后五篇特色文章,其中特色文章只是一篇带有自定义字段is\\u featured设置为1的文章。
我用两种不同类型的代码实现了我想要的:
使用wpdb
<?php
$featuredPosts = $wpdb->get_results("
SELECT ID, post_title FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE $wpdb->postmeta.meta_key = \'is_featured\'
ORDER BY ID DESC LIMIT 5
");
if ($featuredPosts)
{
$htmlOutput = \'\';
foreach ($featuredPosts as $featPost)
$htmlOutput .= \'<br /><a href="\'.get_permalink($featPost->ID).\'">\'.$featPost->post_title.\'</a>\';
}
echo $htmlOutput;
?>
根据“查询监视器”插件,此查询需要0.1秒并生成以下SQL:
SELECT ID, post_title
FROM wp_posts LEFT JOIN wp_postmeta ON(wp_posts.ID = wp_postmeta.post_id)
WHERE wp_postmeta.meta_key = \'is_featured\'
ORDER BY ID DESC
LIMIT 5
使用Wordpress的本机调用
<?php
$featuredPostsRevised = new WP_Query
(
array
(
\'meta_query\' => array
(
array
(
\'key\' => \'is_featured\'
)
)
)
);
while($featuredPostsRevised->have_posts()) : $featuredPostsRevised->the_post();
?>
<br />
<a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a>
<?php
endwhile;
?>
根据“查询监视器”插件,此查询需要0.2秒,并生成更长的SQL:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_postmeta
ON (wp_posts.ID = wp_postmeta.post_id)
WHERE 1=1
AND wp_posts.post_type = \'post\'
AND (wp_posts.post_status = \'publish\'
OR wp_posts.post_status = \'private\')
AND (wp_postmeta.meta_key = \'is_featured\' )
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
我的问题是:
我怎样才能prepare()
我的wpdb
查询我尝试了,但由于第二个参数的原因,无法管理。
使用prepare后,我是否可以假设在安全性和性能方面,wpdb
确实是更好的解决方案吗?
最合适的回答,由SO网友:gmazzap 整理而成
如何准备()我的wpdb查询?我尝试了,但由于第二个参数的原因,无法管理。
这个prepare()
工程解释见Codex, 您需要一个带有占位符和其他参数的查询来替换占位符。如果没有占位符(因此查询中没有可变部分),则可以使用esc_sql 避免SQL注入,但这只有在使用用户输入构建查询时才有意义。OP中的查询是完全硬编码的,因此不需要prepare()
也不是esc_sql()
.
在使用prepare之后,我是否正确地假设在安全性和性能方面,wpdb确实是一个更好的解决方案?
简短回答:no. WP_Query
只是一种更高级别的查询方法,它构建一个查询字符串,然后使用$wpdb
在数据库中运行该sql查询。
如果查看OP中的两个查询,它们是不同的,例如,使用$wpdb
不考虑发布状态、发布日期或发布密码,因此,如果您已删除、计划或私人发布,则使用第一个查询将它们显示给用户。此外,查询不考虑结果排序和其他内容。当然,您可以构建一个考虑所有内容的复杂查询字符串,然后使用$wpdb
, 您有两种可能性:
每当您需要循环时,都要编写一个复杂的硬编码查询字符串:这真的很难处理,而且容易出错。请编写一些以灵活方式处理查询的代码:这将非常困难,您应该编写很多已经由core在中处理的代码WP_Query
: 这毫无意义还有一个重要因素需要考虑:WP_Query
火灾很多filter and action hooks, 成千上万的插件和主题依赖于它们:通过运行手册$wpdb
查询循环会破坏很多东西。
因此,如果需要查询帖子,请使用WP_Query
: 几毫秒不值得数小时的代码和挫折。使用$wpdb
仅当您需要执行核心不处理的查询时。
值得添加@TomJNowell 此处评论:
还应记住:WP_Query
将允许您利用WordPress保留的大量内部缓存,例如在第二次查询时检索一次帖子等。如果您有5万篇帖子要一次全部查询,您可能应该使用作业队列或CLI脚本来完成您的工作(除非您只有数十个用户和大量资金用于服务器)