1. 通过改变query_posts($args)的参数修改主循环
2. 通过WP_Query Class
3. 通过filters更改query_posts()产生的SQL语句
4. 通过$wpdb自定义SQL语句
方法一:通过改变query_posts($args)的参数修改主循环
参考:Function Reference/query posts
query_posts( $args )是用来修改WordPress主循环(Main Loop),使用时应该谨记这一点,如果你所做的查询只是希望在文章底部显示相关文章或者在widget中显示热门文章等等,不要使用query_posts(),因为这会影响与之相关的全局变量,使得主循环中输出的信息不正确。如果一定要使用,记得在做完自己的查询后调用wp_reset_query()。
通过给query_posts()传参数,可以对主循环做一些简单的定制化,例如
<?php
if ( is_home() ) {
query_posts( 'cat=3' );
}
?>
方法二:通过WP_Query Class
WP_Query是一个定义在wp-includes/query.php中的Class,query_posts()就是由WP_Query创建的$wp_query object,当然你可以创建更多的实例,这样就能有效避免对query_posts()进行修改。当然,WP_Query也具备query_posts()的特性,只需创建一个新的实例,就可以像使用query_posts()那样传参数。例如:
<?php $my_query = new WP_Query('category_name=special_cat&posts_per_page=10'); ?>
<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
<!– Do special_cat stuff… –>
<?php endwhile; ?>
方法三:通过filters更改query_posts()产生的SQL语句
参考文章:Custom Queries
通过query_posts() 的filters更改其产生的SQL语句,与第一种方法相比,可以做更复杂的更改,例如与其它数据库表进行联合查询、更改select选择的字段等等。并且可以享用query_posts()带来的好处,例如分页。缺点是可能查询出一些没用的数据,占用更多内存,降低执行效率。
可用的filters有:posts_join, posts_groupby, posts_orderby, posts_distinct, posts_fields, post_limits, posts_where_paged, posts_join_paged以及posts_request。
例如联合查询
add_filter('posts_join', 'geotag_search_join' );
function geotag_search_join( $join )
{
global $geotag_table, $wpdb;
if( is_search() ) {
$join .= " LEFT JOIN $geotag_table ON " .
$wpdb->posts . ".ID = " . $geotag_table .
".geotag_post_id ";
}
return $join;
}
例如改变select选择的字段,默认选择wp_posts.*
add_filter('posts_fields','my_posts_field');
function my_posts_field ($fields){
if( is_home() || is_category() ){
$fields .= ", mytable.*";
}
return $fields;
}
方法四:通过$wpdb自定义SQL语句
参考:Displaying Posts Using a Custom Select Query
这种方法的优势是可定制化最强最灵活,劣势是query_posts()的好处全都没了,比如分页、后台控制首页显示多少文章等等,只有使用query_posts()时分页才会有效。
$wpdb class提供了一系列查询数据库的方法,例如$wpdb->query()允许你抛开所有wordpress的sql语句定义自己的sql。这个类基于ezSQL,语法基本没什么变化,使用很方便,对SQL语句运用自如的人通过该方法可以达到最优化的查询效果。
代码示例:
<?php
$querystr = "
SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = 'tag'
AND $wpdb->postmeta.meta_value = 'email'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
AND $wpdb->posts.post_date < NOW()
ORDER BY $wpdb->posts.post_date DESC
";
$pageposts = $wpdb->get_results($querystr, OBJECT);
?>
通过运行一个自定义的SQL语句获得查询结果,结果保存在$pageposts中。
接下来将结果输出
<?php if ($pageposts): ?>
<?php global $post; ?>
<?php foreach ($pageposts as $post): ?>
<?php setup_postdata($post); ?>
<?php main loop… ?>
<?php endforeach; ?>
<?php else: ?>
未找到文章
<?php endif; ?>
这里调用了setup_postdata()函数,目的是使你可以正常使用the_title(), the_permalink()等模板标签。
通过上述四种方法,在wordpress里自定义查询就不是什么麻烦事了。
3 comments