web-dev-qa-db-ja.com

ob_get_cleanは空の文字列を返し、ob_get_flushは文字列を出力します

私はthe_contentをフィルタリングするためにテンプレート型システムを利用しています。私のフィルタはこの部分コードを含みます:

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

何らかの理由で、これはローカルでは動作しますがテストサーバーでは動作しません(WP Engine - nginx)。ファイルが実際に含まれていることを確認しました。

テストサーバーでは、$contentsは実際には空の文字列です(私はそれを念のためvar_dumpしました。それはstring(0)""です)。

奇妙なのは、上記のコードを次のコードに置き換えたことです。

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

ただ楽しみのために。このコードは、オブジェクトバッファテンプレートページを画面に出力します。オブジェクトバッファを返す必要があるため、ob_flushを使用できません。バッファを出力すると、明らかに私はフィルタから文字列を返す必要があるので、それは間違った場所に表示されます。

ob_get_clean()が正しいバッファの内容をページに出力しているのに、なぜob_end_flush()が空の文字列を返すのですか?

いくつか考えた後、私はinclude_onceを普通の 'ol includeに切り替えました。これにより、サーバーに502エラーが発生するという効果がありました。

だから...私は今、私のフィルタが何らかの理由である種のループを引き起こしている、あるいは何かが何度も呼ばれていると思っているのでしょうか?正直よくわかりません。私は自分の状況で他の人が何をしているのか調査しました、そして私のコードはカスタムテンプレートシステムを使用する他の方法と実質的に同一に見えます。

重要な注意:コールバックがショートコードで呼ばれるとき、それは予想通りに振る舞います。

これの全体的なポイントは、テーマに依存しない方法でCPTのシングルおよびアーカイブ表示にカスタムメタデータ/ページコンテンツレイアウトを使用することです。ショートコードはアーカイブタイプの表示に使用されます(これは手動で作成されたアーカイブであり、通常のアーカイブ - {cpt} .phpではないため、archive-typeと言います)。サイトの所有者がアーカイブページのパーマリンク、タイトル、および全体的なコンテンツを管理できるように、「アーカイブ」ページのショートコードを付けました。可能な限りテーマに依存しないように、the_contentにフィルタをかけました。

フルフィルターコード:

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

私のコードが失敗したのは、それがメモリの限界に達したためです。

The_contentにフィルタを追加し、WYSIWYGタイプのメタデータを取得するために別のプラグインのAPI(Custom Field Suite)を呼び出していました。このタイプのフィールドは_contentフィルタを通過するので、無限ループに遭遇しました。

エラーロギングが非常に限られているため、WP Engineでこれを見つけることができませんでした。

MediaTempleサーバーでサイトをテストしたところ、正しいエラーメッセージが表示されました。

これを修正するために、メタデータ取得メソッドを呼び出す前にthe_contentからフィルタを削除し、その後追加しました。

2
Josh Levinson