web-dev-qa-db-fra.com

si/sinon sur requête personnalisée donne 200 OK si la condition n'est pas remplie?

Quoi? Je modifie mon thème pour afficher les commentaires d'un article sur une page séparée.

Comment? Généralement sur la base de cette réponse mais avec des contrôles et un code améliorés. Voici donc à quoi ressemble mon page-comments.php (un peu):

(Le code est très facile à parcourir, faites-moi confiance!)

<?php get_header(); ?>

<?php
    /*
     * (Example URL: example.com/comments/?original_post=ID)
     *
     * Check if HTTP variable (original_post) exists in queried URL,
     * AND that it is set to some value (ID), AND that the value (ID) is a number.
     */
    if( array_key_exists( 'original_post', $_GET ) && isset( $_GET['original_post'] ) && ctype_digit( $_GET['original_post'] ) ) {

        $query_original_post = new WP_Query( array(
            'posts_per_page' => 1,
            'p'              => $_GET['original_post'],
            'post_type'      => 'any',
        ) );

        if( $query_original_post->have_posts() ) {

            while ( $query_original_post->have_posts() ) : $query_original_post->the_post();

                // [...]

            endwhile;
            wp_reset_postdata();

        } else {

            /*
             * Return 404 error if there are no posts
             */
            global $wp_query;
            $wp_query->set_404();
            status_header( 404 );
            nocache_headers();
            get_template_part( '404', 'archive' );
            //exit();

        }

    } else {

        /*
         * Return 404 error if the HTTP variable (original_post) doesn't
         * exist in queried URL, OR it isn't set to any value (ID),
         * OR the value (ID) isn't a number.
         */
        global $wp_query;
        $wp_query->set_404();
        status_header( 404 );
        nocache_headers();
        get_template_part( '404', 'archive' );
        //exit();

    }
?>

<?php get_footer(); ?>

(Le code que j'utilise pour renvoyer une erreur 404 est basé sur ces deuxsolutions .)

Comme vous pouvez le constater, je vérifie deux fois le code (, du moins c'est ce que j'avais l'intention de faire ):

  1. Vérifiez si la variable HTTP (original_post) existe dans l'URL interrogée ET qu'elle est définie sur une valeur (ID) ET que la valeur (ID) est un nombre. Sinon, renvoyer une erreur 404 avec les en-têtes appropriés.

  2. Vérifiez si la requête WordPress personnalisée ($query_original_post) a des résultats à boucler. Sinon, renvoyer une erreur 404 avec les en-têtes appropriés.

Problème:

  1. Est-ce la bonne façon de le faire? (ou du moins, peut-il être plus simple?)

  2. (Si oui à # 1) Cela semble fonctionner, mais renvoie un en-tête 200 OK lorsque je vais à une URL telle que: example.com/comments/?original_post=NUMBER, où NUMBER est un entier positif de plus de 4 chiffres (par exemple, 14532 ).

    Je ne comprends pas la relation. Pourquoi quelque chose comme `example.com/comments/? Original_post = 14532` renvoie-t-il un en-tête 200 OK lorsque je suis connecté à WordPress et une erreur 404 (ce qui devrait être le cas) lorsque je ne le suis pas?

1
its_me

Les en-têtes sont envoyés bien avant que vous essayiez de les modifier. Les en-têtes sont envoyés par les actions associées à get_header(). Par conséquent, au moment où votre code est exécuté, il est trop tard pour modifier les en-têtes. Vous pouvez le démontrer avec une expérience simple. Essayez chacune des solutions suivantes:

get_header(); 
status_header( 404 );

et

status_header( 404 );
get_header(); 

Dans un fichier modèle et regardez la sortie avec un outil comme HttpFox ou Wireshark (si vous voulez vraiment avoir du plaisir :)).

Pour changer efficacement les en-têtes, vous devez exécuter votre logique avant la get_header().

Je crois que cela produira l'effet souhaité avec moins de lignes de code à démarrer:

/*
* (Example URL: example.com/comments/?original_post=ID)
*
* Check if HTTP variable (original_post) exists in queried URL,
* AND that it is set to some value (ID), AND that the value (ID) is a number.
*/

if( 
  array_key_exists( 'original_post', $_GET ) 
  && isset( $_GET['original_post'] ) 
  && ctype_digit( $_GET['original_post'] ) 
) {
  $query_original_post = new WP_Query( 
    array(
      'posts_per_page' => 1,
      'p'              => $_GET['original_post'],
      'post_type'      => 'any',
    ) 
  );
  if( !$query_original_post->have_posts() ) {
    global $wp_query;
    $wp_query->set_404();
    status_header( 404 );
    nocache_headers();
  } 
}

get_header();
if( !empty($query_original_post) && $query_original_post->have_posts() ) {
  while ( $query_original_post->have_posts() ) {
    $query_original_post->the_post();
    // [...]
  }
  wp_reset_postdata();
} else {
  get_template_part( '404', 'archive' );
}
get_footer();

Et pour l'amour de tout ce qui est saint, veuillez ne pas utiliser PHP balises d'ouverture et de fermeture, sauf si vous en avez réellement besoin.

3
s_ha_dum