일부 404에서 루프가 비어 있지 않은 이유는 무엇입니까?


10

이상한 문제가 발생했습니다.

세 개 이상의 수준으로 임의의 URL에 액세스한다고 가정 해보십시오.

http://example.com/a/b/c
http://example.com/a/b/c/d
...

그런 다음 is_404()입니다 true. 여태까지는 그런대로 잘됐다. 그러나 어떤 이유로 마지막 게시물이 쿼리됩니다.

$wp_query->request

이다

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
    FROM wp_posts 
    WHERE 1=1 
        AND wp_posts.post_type = 'post' 
        AND (
            wp_posts.post_status    = 'publish' 
            OR wp_posts.post_status = 'private'
            ) 
    ORDER BY wp_posts.post_date DESC 
    LIMIT 0, 5

그렇다면 물론 have_posts()돌아 오는 true것입니다. 누군가 이것을 설명 할 수 있습니까?

내가 지금까지 알아 낸 것 :

WP가 3 개 이상의 레벨에서만 시작하는 이유는 WP가 게시물과 첨부 파일을 찾기 전에 다른 동작을 유발하기 때문입니다.

WP가 요청을 한 시점에서 404로 인식하더라도 가장 최근 게시물을 가져 오는 것으로 보입니다. 의 도움으로 @kaiser 및 @GM I에서 어딘가에이 아래로 추적 한 /wp-includes/class-wp.php:608


당신이 페이지의 코드를 추가하지 않으면 당신을 돕기 어려울 것입니다
— Tomás Cot

3
이것은 내 코드에만 국한되지 않습니다. 모든 기본 테마와 함께 새로 설치 한 경우 이와 같이 작동합니다.
— kraftner

사용자 정의 테마가 작동하지 않는 테마를 하나 이상 지정할 수 있습니까? 특정 매개 변수를 사용하고 있습니까? 슬러그를 교체 했습니까? 어떤 버전의 WP를 사용하고 있습니까?
— Tomás Cot

정말요 그러나 원한다면 스물 일레븐을 시도하십시오.
— kraftner

모든 질문에 대해 죄송합니다. 게시물이 표시되고 있다고 생각했습니다.
— Tomás Cot

답변:


9

당신은 놀랄지도 모르지만 거기에는 이상한 것이 없습니다.

우선 워드 프레스에서 프론트 엔드 URL을 방문 할 때 쿼리를 실행한다는 것을 명확히하자. 항상.

이 쿼리는 WP_Query다음을 통해 실행되는 것과 마찬가지로 표준 입니다.

$query = new WP_Query( $args );

한 가지 차이점이 있습니다. $args변수는이 WP::parse_request()방법을 사용하여 WordPress에 의해 생성됩니다 . 그 방법은 URL과 다시 쓰기 규칙을보고 URL을 인수 배열로 변환하는 것입니다.

그러나 URL이 유효하지 않기 때문에 해당 메소드가 그렇게 할 수없는 경우 어떻게됩니까? 쿼리 인수는 다음과 같은 배열입니다.

array( 'error' => '404' );

(출처 여기 와 여기 ).

배열이에 전달됩니다 WP_Query.

이제 시도하십시오 :

$query = new WP_Query( array( 'error' => '404' ) );
var_dump( $query->request );

쿼리가 OP의 쿼리라는 것에 놀랐습니까? 난 아니에요.

그래서,

  1. parse_request() 오류 키를 사용하여 배열을 만듭니다.
  2. 해당 배열이에 전달되어 WP_Query실행됩니다.
  3. handle_404()쿼리 후에 실행 되고 'error'매개 변수 is_404()를보고 true로 설정 합니다.

그래서, have_post()와 is_404()관련이 없습니다. 문제는 WP_Query무언가 잘못되었을 때 쿼리를 단락시키는 시스템이 없다는 것입니다. 따라서 일단 객체가 빌드되면 일부 인수를 전달하면 쿼리가 실행됩니다 ...

편집하다:

이 문제를 극복하는 데는 두 가지 방법이 있습니다.

  • 404.php템플릿을 만듭니다 . 워드 프레스는 404 개의 URL에로드 할 것이므로 확인할 필요가 없습니다.have_posts()
  • $wp_query404에서 다음과 같이 강제 로 비 웁니다.

    add_action( 'wp', function() {
        global $wp_query;
        if ( $wp_query->is_404() ) {
            $wp_query->init();
            $wp_query->is_404 = true; // init() reset 404 too
        }
    } );

4
이것이 일반적으로 발생하지 않는 이유 는 404가 일반적 으로 query의 결과 이기 때문 이라고 덧붙 입니다. 그러나이 경우 일치하지 않는 다시 쓰기 규칙 ( $wp->matched_rule) 의 결과 이지만주의를 기울이지 않기 때문에 쿼리가 여전히 동작을 수행하고 있습니다.
— Rarst

+1. 예, 쿼리는주의를 기울이지 않으며 현재 코드를 사용하면 중지 할 방법이 없으므로주의를 기울일 수 없습니다 . 예를 들어, 유효하지 않은 분류법을 쿼리 WHERE 1=0할 때 쿼리를 중지 할 수 없기 때문에 sql에서 WordPress 세트 를 쿼리하면 아무 것도 반환하지 않는 쿼리를 강제 실행합니다 ... @Rarst
— gmazzap

알았어 이제 알겠다 따라서 남아있는 실제 질문은 왜 WP_Query가 아무 것도 반환하지 않을 때 합리적인 인수가 전달되지 않은 경우 게시물을 가져 오는 기본 쿼리를 가정하는 이유는 무엇입니까?
— kraftner

2
@kraftner는 WordPress에서 쿼리 실행을 피할 수 없으며 적절한 인수가없는 경우 두 가지 선택 사항이 있습니다 : 유효하지 않은 분류법을 쿼리 할 때와 같이 위의 주석을 볼 때와 같이 아무것도 반환하지 않는 쿼리를 실행하거나 기본 쿼리를 실행하십시오 . 이 경우 WP가 후자를 선택하는 이유는 핵심 개발자에게 질문해야하는 Q입니다.)
— gmazzap

@ TomásCot 물론이지만 실패하면 실제로 실패하고 완전히 관련이없는 것을 반환하지 않기를 바랍니다. 어쨌든, 지금 상황이 정리되었고 추가 is_404()점검 을해야합니다 .
— kraftner
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.