web-dev-qa-db-de.com

ob_get_clean gibt eine leere Zeichenkette zurück, ob_get_flush gibt eine Zeichenkette aus

Ich benutze ein Template-System, um the_content zu filtern. Mein Filter enthält diesen Teilcode:

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

Aus irgendeinem Grund funktioniert dies lokal, jedoch nicht auf einem Testserver (WP Engine - nginx). Ich habe überprüft, dass die Datei tatsächlich enthalten ist.

Auf dem Testserver ist $contents eine leere Zeichenfolge (ich habe sie zwar ausgegeben, aber es handelt sich um string(0)"").

Was bizarr ist, ist, dass ich den obigen Code durch Folgendes ersetzt habe:

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

nur zum Spaß. Dieser Code gibt die objektgepufferte Vorlagenseite auf dem Bildschirm aus. Ich kann ob_flush nicht verwenden, da ich den Objektpuffer zurückgeben muss. Die Ausgabe des Puffers führt dazu, dass er an der falschen Stelle angezeigt wird, offensichtlich, weil ich die Zeichenfolge aus dem Filter zurückgeben muss.

Warum gibt ob_get_clean() eine leere Zeichenfolge zurück, während ob_end_flush() den richtigen Pufferinhalt auf der Seite ausgibt?

Nach einigem Überlegen habe ich den include_once auf plain 'ol include umgestellt. Dies hatte zur Folge, dass der Server einen 502-Fehler generierte.

Also ... ich denke jetzt, dass mein Filter aus irgendeinem Grund eine Art Schleife verursacht oder dass etwas mehrmals aufgerufen wird? Ich bin mir ehrlich gesagt nicht sicher. Ich habe nachgeforscht, was andere in meiner Situation getan haben, und mein Code sieht praktisch identisch mit anderen Methoden zur Verwendung eines benutzerdefinierten Vorlagensystems aus.

Ein wichtiger Hinweis: Wenn der Rückruf über eine Kurzwahlnummer angerufen wird, verhält er sich wie erwartet.

Der springende Punkt dabei ist die Verwendung eines benutzerdefinierten Layouts für Metadaten/Seiteninhalte für Einzel- und Archivanzeigen von CPTs auf themenunabhängige Weise. Der Shortcode wird für die Anzeige des Archivtyps verwendet (ich sage Archivtyp, weil es ein manuell induziertes Archiv ist, kein typisches Archiv- {cpt} .php). Ich habe einen Shortcode für die Archivseiten festgelegt, damit der Websitebesitzer die Kontrolle über den Permalink, den Titel und den Gesamtinhalt der Archivseite hat. Ich habe the_content mit einem Filter ausgewählt, damit es möglichst themenunabhängig ist.

Vollständiger Filtercode:

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

Der Grund, warum mein Code fehlschlug, war das Erreichen eines Speicherlimits.

Ich habe einen Filter zu the_content hinzugefügt und die API eines anderen Plugins (Custom Field Suite) aufgerufen, um einige Metadaten vom Typ WYSIWYG abzurufen. Diese Art von Feld durchläuft den Filter "the_content", sodass ich eine Endlosschleife getroffen habe.

Ich konnte dies bei WP Engine nicht herausfinden, da die Fehlerprotokollierung sehr eingeschränkt ist.

Am Ende habe ich die Site auf einem MediaTemple-Server getestet, wodurch die richtige Fehlermeldung angezeigt wurde.

Um dies zu beheben, habe ich den Filter aus dem_content entfernt, BEVOR ich den Metadaten-Getter aufgerufen habe, und ihn anschließend wieder hinzugefügt.

2
Josh Levinson