if (have_posts ()), while (have_posts ())가 충분하지 않은 이유는 무엇입니까?


22

"루프"에 대한 질문이 있습니다.

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

Loop WordPress Codex 페이지 에서 가져온 코드 입니다.

왜 내가 if참여 해야 합니까? while루프 가 있으면 잘 작동합니다.

if성명 이 없으면 어떤 경우에 문제가 발생 합니까?

편집하다

@Chip의 답변을 수락했습니다. 그러나 솔직히 말하면 마지막 부분 만 필요합니다.

나는 지금 내 질문에서 알고 싶은 것을 알고 있습니다.

if한 번만 작성해야하는 머리글이나 바닥 글을 넣으려는 경우에는 필요할 때만 statement입니다. "래퍼"를 사용하지 않으면 if명령문이 필요하지 않습니다.


2
the_content를 읽기 전에 투표했는데, the_title은 결정적입니다!
brasofilo

우수 (최종) 편집 대부분의 사람들은 다른 것을 사용하지 않고 if와 while을 직접 사용합니다. 복사 및 붙여 넣기 때문일 수 있습니다.
Herbert Van-Vliet

답변:


29

해당 컨텍스트에 대한 쿼리가 게시물을 반환하지 않더라도 WordPress 템플릿 로더에는 여러 상황에서 적절한 컨텍스트 템플릿 파일이 포함됩니다. 예를 들면 다음과 같습니다.

  • 주요 블로그 게시물 색인
  • 카테고리 아카이브 색인 (카테고리는 존재하지만 게시물이 없습니다)
  • 태그 아카이브 색인 (태그는 있지만 게시물이 없습니다)
  • 저자 아카이브 색인 (저자 존재하지만 게시물이 없음)
  • 검색 결과 색인

따라서 이러한 경우 적절한 템플리트 파일이로드되지만 조회는 게시물을 리턴하지 않으므로 게시물이 출력되지 않습니다.

개념 증명 예 :

따라서 이러한 컨텍스트에서 템플릿 파일이 if ( have_posts() )조건부 를 포함하는 것이 유용 합니다.

다른 컨텍스트에서 쿼리가 게시물을 반환하지 않으면 템플릿 파일이로드되지 않습니다. 예를 들면 다음과 같습니다.

  • 단일 블로그 게시물
  • 정적 페이지

이러한 맥락에서, if ( have_posts() )아마도 불필요 할 것입니다.

편집하다

쿼리가 the_post ()에 의해 호출되었음을 이해합니다. while (have_posts ())가 존재하면 게시물이 없으면 쿼리가 발생하지 않습니다.

무슨 일이 일어나고 있는지 이해하려면 워드 프레스 작업의 순서를 살펴 봐야합니다 . 시작하기 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_redirect
  • 템플릿이로드 / 출력됩니다. 템플릿 은 다음 작업 을 시작합니다 .
    • get_header
    • wp_head
    • the_post
    • dynamic_sidebar
    • get_footer
    • wp_footer

따라서에 the_post의해 실행 되는 쿼리는 구문 분석되고 게시물을 가져오고 템플릿이로드 된 후에도the_post() 발생합니다 .

나는 당신이 내가 모르는 많은 정보를 제공하는 것에 대해 매우 감사하지만, 이것은 내가 요구 한 것이 아닙니다.

아, 그러나 나는 그것이 당신이 요구 한 그대로 라고 생각합니다 .

실제 질문은 : 유효한 쿼리 반환은 무엇입니까? 카테고리 아카이브 색인과 같은 컨텍스트의 경우, 조회 된 카테고리 ID가 존재하는 경우 해당 카테고리에 지정된 게시물이없는 경우에도 조회가 유효하며 카테고리 템플리트가로드됩니다 .

왜? 구문 분석되는 쿼리는 (IIRC)입니다 &cat={ID}. 이는 해당 카테고리에 지정된 게시물이 없어도 유효한 쿼리 이므로 구문 분석시 404가되지 않습니다.

이 경우 유효한 쿼리가 있고 템플릿 파일이로드 되었지만 게시물은 없습니다 . 따라서 if ( have_posts() ), 사실입니다 관련. 다시 한 번, 예는 다음과 같습니다. 카테고리가 있지만 게시물이 할당되지 않았습니다. 카테고리 템플릿 파일이로드 if ( have_posts() )되고을 반환false 합니다.

게시물이 실제로 존재하지 않기 때문에 단일 블로그 게시물 및 정적 페이지와 같은 게시물 변수 ( &p={ID}) 를 포함하는 쿼리에는 적용 되지 않으며 구문 분석시 쿼리는 유효한 객체를 반환하지 않습니다.

편집 2

카테고리 템플릿에 if (have_posts ())가없고 카테고리에 게시물이 없는지 올바르게 이해하면 게시하지 않고 category-sample.php를 반환해야하지만 404.php를 반환합니다. 맞습니까?

기억하십시오 : 템플릿은에서 선택됩니다 template_redirect. 따라서 쿼리가 유효하면 적절한 템플릿 파일이로드됩니다. 쿼리가 유효하지 않으면 404 템플릿이로드됩니다.

따라서 일단 템플릿이로드되면 (예 : 카테고리 템플릿) 루프가 출력되면 템플릿은 변경되지 않습니다 .

동작 순서를 다시 살펴보십시오.

  • parse_query
  • pre_get_posts
  • wp
  • template_redirect- 템플릿이 선택되어 여기에로드됩니다. 이것은 리턴 포인트의 템플릿 포인트입니다 . 이 시점 이후에는 템플릿을 변경할 수 없습니다.
  • ...
  • the_post- POSTDATA는 설정은 루프 호출의 일부로서, 여기에있다. 이 호출됩니다 템플릿 내부템플릿은 변경되지 않습니다 질의 객체의 데이터를 기반

최종 편집

그리고 게시물의 존재를 확인하면서 왜 같은 테스트를 두 번 실행해야한다고 주장합니다. 그것은 내가 그것에 대해 묻고있는 첫 번째 요점으로부터의 나의 질문입니다.

그리고 결국, 나는 이해합니다 : 당신의 질문은 WordPress 또는 WordPress Loop 와 아무 관련이 없습니다 . 동일한 조건을 확인 while하는 if조건부 내에 임의의 PHP 루프를 래핑하는 방법을 묻습니다 .

이 질문은 WPSE의 범위를 벗어 났지만 간단히 설명하겠습니다.

if조건은 바이너리 평가이다 : 그것은 하나의 truefalse, 그리고 무슨 일 안에 그 조건으로하는 실행 하면 .

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루프를.


2
단 하나의 게시물 / 페이지 템플릿에서는 오랫동안 사용 the_post();하기 때문에 while불필요 하기 때문에 사용합니다 . 정보의 완전성을 위해 +1.
gmazzap

@GM if( have_posts() )문장을 제거하는 것이 의미가 있습니다 (내가 찾은 것입니다). 단일 페이지 에서만 사용하지 마십시오 the_post()!
Sunyatasattva

@ ChipBennett 모든 고려, 당신은 if( have_post() )의 맥락에서 전체 루프 전에 조건 을 제거하는 것이 안전하다고 생각합니까single-*.phppage-*.php템플릿 파일 하십니까?
Sunyatasattva

1
"안전"은 실제로이 맥락에서 결정적인 의미가 없습니다.
Chip Bennett

10

Chip의 답변을 개선하는 것은 실제로 불가능하지만 추격을 줄이기 위해 :

사용 if게시물없을 때 다른 것을 표시 부분을 . 예를 들어 날짜 또는 카테고리 보관 페이지에서 특히 유용합니다. 누군가 게시물이없는 페이지를 탐색하는 경우 루프가 실행되지 않으므로 아무 것도 표시되지 않고 메시지가 표시되는 것이 좋습니다.

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;

그리고 이것은 모두 알아야 할 것입니다.
Herbert Van-Vliet

0

지금까지 답변에 포함되지 않은 몇 가지 고려 사항이있을 수 있습니다. if 문을 생략하지 않는 것이 좋습니다.

if 문은 일반적으로 다음과 같은 용도로 사용됩니다.

  • no posts found문제의 카테고리에 할당 된 기사가 없음을 나타내는 것과 같은 결과가 출력 됩니다.
  • 기사 전후에 주변 HTML (ul과 같은)을 출력 해야하는지 결정합니다.

새 후크가 추가되면 어떻게됩니까?

if 문을 사용하지 않는 또 다른 가능한 문제는 wordpress 팀이 처음에 트리거하는 새 후크를 추가하기로 결정한 경우입니다. $wp_query->have_posts() 호출에서 경우 잘못된 시간에 트리거된다는 것입니다. 그리고 예기치 않은 동작이 발생하면 사양을 제대로 따르지 않는 것이 잘못입니다.

다른 개발자는 워드 프레스 루프의 특정 구조를 기대합니다

다른 개발자가 전체 워드 프레스 루프를 기대한다고 가정합니다. 따라서 존재하지 않는 if 문을 검색하도록하는 것은 좋지 않습니다.


-1

나는 이것을 제어 구조 이론의 근본적인 질문으로 본다. 조건 (have_posts ())이 처음으로 false로 평가되는 경우 while 루프 내의 동봉 된 블록은 한 번만 실행되지 않습니다.

따라서 if ( have_posts() )WordPress 루프 의 목적은 while 조건이 평가되기 전에 have_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; ?>

3
단순화는 유효하지 않은 PHP이므로 if 문이없는 else 문이 있습니다. 기껏해야 그것은 읽기 어렵다
톰 J 노웰

1
if때문에의 존재 else그 후. 다른 이유는 없습니다. 게시물이 없으면 아무 것도 표시하지 않는 것보다 멋진 "게시물 없음"메시지를 표시하는 것이 좋습니다.
Otto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.