为什么我要放if(has_posts()),While(Have_Posts())还不够?

时间:2013-10-09 作者:ironsand

我有一个关于“循环”的问题。

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e(\'Sorry, no posts matched your criteria.\'); ?></p>
<?php endif; ?>
代码取自The Loop WordPress Codex page.

我为什么要把if 部分好像有while 回路,工作正常。

在什么情况下,如果没有if 陈述

编辑我接受了@Chip的回答。但老实说,我只需要最后一部分。

我现在知道我想从我的问题中知道什么了。

if 语句仅在必要时才可用,前提是要放置只应写入一次的页眉或页脚。如果你不使用“包装器”,那么if 无需声明。

4 个回复
最合适的回答,由SO网友:Chip Bennett 整理而成

WordPress模板加载器在许多情况下都会包含适当的上下文模板文件,即使对该上下文的查询没有返回帖子。例如:

主博客帖子索引(Category exists,但没有帖子)类别存档索引(Category exists,但没有帖子)

  • 标记存档索引(Tag exists,但没有帖子)
  • 作者存档索引(Author exists,但没有帖子)
  • 搜索结果索引
    • 因此,在这些情况下,将加载适当的模板文件,但不会输出帖子,因为查询不会返回帖子。

      概念验证示例:

      • Category exists, but has no posts (包括类别模板)Category does not exist (包括404模板)因此,在这些上下文中,模板文件包括if ( have_posts() ) 有条件的

        在其他上下文中,如果查询不返回帖子,则永远不会加载模板文件。例如:

        在这些上下文中,单个博客帖子,if ( have_posts() ) 可能没有必要。

        编辑

        我知道查询是由\\u post()调用的,对吗?如果while(have\\u posts())存在,则如果没有post,则永远不会发生查询。

        要了解发生了什么,you have to look at the order of WordPress actions. 从开始wp_loaded (为了清楚起见,省略一些):

        • wp_loaded
        • parse_request
        • send_headers
        • parse_query
        • pre_get_posts
        • wp
        • template_redirect
        • get_header
        • wp_head
        • the_post
        • wp_footer

          调用查询:

          • parse_query
          • pre_get_posts
          • wp
        • 选择模板:
          • template_redirectget_header
          • wp_head
          • the_post
          • dynamic_sidebar
          • get_footer
          • wp_footerthe_post, 激发者the_post(), 在解析查询、获取帖子和加载模板很久之后发生。

            我非常感谢你提供了很多我不知道的信息,但这不是我所要求的。

            哦,但我相信这正是你所要求的。

            真正的问题是:什么是有效的查询返回?对于诸如类别存档索引之类的上下文,如果查询的类别ID存在,即使没有为该类别分配帖子,查询也是有效的,并且会加载类别模板。

            为什么?因为正在分析的查询是(IIRC)&cat={ID} - 这是一个有效的查询,即使没有为该类别分配帖子,也不会在解析时产生404。

            在这种情况下,您将得到一个有效的查询,并加载了一个模板文件,但没有帖子。因此if ( have_posts() ), <事实上,em>是相关的。同样,这里有一个例子:category exists, but has no posts assigned. Category template file is loaded, with if ( have_posts() ) returning false.

            对于包含post变量的查询,这将不适用(&p={ID}) 例如单个博客帖子和静态页面,因为帖子实际上不存在,并且在解析时,查询将不会返回有效对象。

            编辑2

            如果我正确理解类别模板中是否没有If(have\\u posts())且类别没有post,则返回404。php,即使它应该是返回类别示例。php无post。是这样吗?

            否。请记住:模板是在template_redirect. 因此,如果查询有效,则加载相应的模板文件。如果查询无效,则加载404模板。

            因此,一旦加载了模板(例如类别模板),循环一旦输出,模板就不会更改。

            再次查看操作顺序:

            • parse_query
            • pre_get_posts
            • wp
            • template_redirect - template is chosen and loaded here. 这是模板的止回点。在此点之后,模板无法更改
            • the_post - postdata is setup here, as part of the loop call. 这在模板内部称为,模板不会根据查询对象中的可用数据进行更改,并且我声称,在检查帖子是否存在的同时,为什么要运行两次相同的测试。这是我从第一点开始提出的问题,我只问了这一点。

              至此,我终于明白了:一直以来,你的问题与WordPress或WordPress循环无关。您正在询问如何包装任意PHPwhile 内部循环if 检查相同条件的条件。

              这个问题超出了WPSE的范围,但我将简要解释:

              parse_query六 conditional是一个二进制计算:它是truefalse, 在该条件的内部发生的事情被执行一次。

              A.while 条件是一个循环:基于某种计数器,它在一些离散的时间段内保持为真;并且在该条件的内部发生的事情被执行几次,对于计数器的每次迭代一次。

              那么,假设您想要输出一个无序的事物列表,如果该事物列表已填充。如果您使用while 循环,并忽略if 包装器,您的标记如下所示:

              <ul>
              <?php while ( list_of_things() ) : ?>
                  <li><?php the_list_item(); ?></li>
              <?php endwhile; ?>
              </ul>
              
              如果list_of_things() 为空,渲染输出将为:

              <ul>
              </ul>
              
              这会留下不必要的(和无效的)标记。

              但如果你加上if 条件包装器,可以执行以下操作:

              <?php if ( list_of_things() ) : ?>
                  <ul>
                  <?php while ( list_of_things() ) : ?>
                      <li><?php the_list_item(); ?></li>
                  <?php endwhile; ?>
                  </ul>
              <?php endif; ?>
              
              如果list_of_things() 为空,则不会输出任何标记。

              这只是一个例子。这有很多用途if 条件包装器,以及if 条件包装的用途与while

    SO网友:Tom Auger

    要改进芯片上的答案确实是不可能的,但要切入主题:

    使用if 如果你想让一些不同的东西出现no posts. 这尤其有用,例如,在日期或类别存档页面上。如果有人导航到一个没有帖子的页面,最好有一条这样的消息,而不是什么都没有出现,因为循环永远不会执行。

    if ( have_posts() ):
      // Yep, we have posts, so let\'s loop through them.
      while ( have_posts() ) : the_post();
      // do your loop
      endwhile;
    else :
      // No, we don\'t have any posts, so maybe we display a nice message
      echo "<p class=\'no-posts\'>" . __( "Sorry, there are no posts at this time." ) . "</p>";
    endif;
    

    SO网友:Rob Monhemius

    到目前为止,答案中可能还没有包括一些考虑因素。不建议省略if语句。

    The if statement is commonly used to:

    <输出如下内容no posts found 表明所讨论的类别没有分配给它的物品

    What if a new hook is added?

    不使用if语句的另一个可能问题是,如果wordpress团队决定添加一个在第一个$wp_query->have_posts() 呼叫,它会在错误的时间触发。如果这导致了意外的行为,那将是你没有正确遵守规范的错。

    Other devs expect to see a specific structure for the wordpress loop

    我想其他开发人员希望看到整个wordpress循环。因此,让他们搜索不存在的if语句可能是个坏主意。

    SO网友:Schparky

    我认为这是控制结构理论的一个基本问题。如果条件(have\\u posts())第一次计算为false,while循环中的封闭块甚至不会执行一次。

    因此if ( have_posts() ) 在WordPress循环中,仅在计算while条件之前执行一次have\\u posts()函数。如果have_posts() 没有副作用,那么if ( have_posts() ) 完全没有意义。如果have_posts() 确实有副作用,可以简化如下:

    <?php have_posts(); ?>
    <?php while ( have_posts() ) : the_post(); ?>
    <?php endwhile; else: ?>
    <p><?php _e(\'Sorry, no posts matched your criteria.\'); ?></p>
    <?php endif; ?>
    

    结束

    相关推荐

    Skip foreach loop

    这里有一个小的编码问题。代码:if ($categories) { foreach ($categories as $tag) { $tag_link = get_category_link($tag->term_id); //new line if (isset($instance[\'new-line\'])) { $html .= \"