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

参考文章:Class Reference/WP Query

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里自定义查询就不是什么麻烦事了。

Last modification:April 11th, 2020 at 09:18 pm
如果觉得我的文章对你有用,请随意赞赏