web-dev-qa-db-fra.com

ob_get_clean retourne une chaîne vide, ob_get_flush renvoie une chaîne

J'utilise un système de type template pour filtrer the_content. Mon filtre contient ce code partiel:

ob_start();
include_once ( self::$dir . 'views/templates/' . $post_type . '/' . $display . '.php' );
$contents = ob_get_clean();
return $contents;

Pour une raison quelconque, cela fonctionne localement mais pas sur un serveur de test (WP Engine - nginx). J'ai vérifié que le fichier est bien inclus.

Sur le serveur de test, $contents est en fait une chaîne vide (je l’ai var_dump’ed pour en être sûr, c’est string(0)"").

Ce qui est bizarre, c’est que j’ai remplacé le code ci-dessus par:

ob_start();
include_once ( self::$dir . 'views/templates/' . $post_type . '/' . $display . '.php' );
ob_flush_clean();

juste pour le fun. Ce code affiche la page de modèle en tampon d'objet à l'écran. Je ne peux pas utiliser ob_flush car je dois renvoyer le tampon d'objet. La sortie de la mémoire tampon provoque son affichage au mauvais endroit, évidemment parce que je dois renvoyer la chaîne à partir du filtre.

Pourquoi ob_get_clean() renvoie-t-il une chaîne vide alors que ob_end_flush() affiche le contenu correct de la mémoire tampon vers la page?

Après réflexion, j'ai changé le include_once en plain 'ol include. Cela a eu pour effet de générer une erreur 502 sur le serveur.

Donc ... je pense maintenant que pour une raison quelconque, mon filtre provoque un type de boucle ou que quelque chose soit appelé plusieurs fois? Honnêtement, je ne suis pas sûr. J'ai recherché ce que d'autres personnes dans ma situation ont fait et mon code a une apparence pratiquement identique à d'autres méthodes d'utilisation d'un système de modèles personnalisé.

Une remarque importante: lorsque le rappel est appelé via un shortcode, il se comporte comme prévu.

L'intérêt de ceci est d'utiliser une disposition de métadonnées/contenu de page personnalisée pour des affichages uniques et archivés de CPT de manière indépendante du thème. Le shortcode est utilisé pour l'affichage de type archive (je parle de type archive car il s'agit d'une archive induite manuellement, pas d'un fichier archive typique {cpt} .php). Je suis allé avec un shortcode pour les pages 'archive' afin que le propriétaire du site puisse contrôler le permalien, le titre et le contenu général de la page d'archive. Je suis allé avec un filtre sur the_content afin qu'il puisse être aussi indépendant que possible du thème.

Code de filtre complet:

add_filter( 'the_content', array( $this, 'filter_content' ) );
function filter_content($content) {

    global $post;

    if( !$this->we_belong_here() ) {
    //does post type check

        return $content;

    }

    $display = 'archive';

    if( is_single( $post ) ) {

        $display = 'single';

    }

    return $this->shortcode( array( 'post_type' => $post->post_type, 'display' => $display, 'content' => $content, 'method' => 'class' ) );

}

function shortcode($atts) {

    extract( shortcode_atts( array(

        'post_type' => '',

        'display' => 'archive',

        'method' => 'shortcode',

        'content' => ''

    ), $atts ) );

    ob_start();

    include ( self::$dir . 'views/templates/' . $post_type . '/' . $display .'.php' );

    $contents = ob_get_clean();

    if($contents) return $contents; else return $content;

}
2
Josh Levinson

La raison pour laquelle mon code échouait était dû au fait qu'il atteignait une limite de mémoire.

J'ajoutais un filtre à the_content et appelais l'API d'un autre plugin (Custom Field Suite) pour obtenir des métadonnées de type WYSIWYG. Ce type de champ traverse le filtre the_content, alors je frappais une boucle infinie.

Je ne pouvais pas le savoir sur WP Engine, car la journalisation des erreurs était très limitée.

J'ai fini par tester le site sur un serveur MediaTemple, ce qui a entraîné l'affichage du message d'erreur correct.

Pour résoudre ce problème, j'ai supprimé le filtre de the_content AVANT d'appeler le getter de métadonnées, puis de le rajouter après.

2
Josh Levinson