web-dev-qa-db-ja.com

ポストグローバルを信頼すべきでしょうか。

@toschoが この回答 にコメントを残しました。グローバルな範囲、特に$postのようなポストグローバルに関して、私たちはどの程度の信頼を得るべきでしょうか。

だから何?グローバル変数は、チェックが実行される前に全員から上書きされる可能性があります。それがグローバル変数のポイントです:グローバルアクセス。

例えば$postは確かにほとんどがテーマ自体の中でまたはプラグインによって修正されるグローバルの1つです。それにもかかわらず、例えば、関連する投稿を設定するために、特定のテンプレート内の他のアプリケーションで最も一般的に使用されているものです。

カスタムクエリの使用に起因する特定の問題に対するいくつかの投稿への回答(およびコメントアウト) から、ほとんどの問題はカスタムクエリがリセットされないことが原因であることが実際に際立っています。メインクエリ).

これから、$postは信頼できないことが明らかです。カスタムクエリを利用するように書かれたコードの一部は、$postグローバルを変更する可能性があり、それが(関連記事のように)何かを壊す可能性があります。

ほんの一握りのWordPress開発者だけが実際にコアの内部の働きに十分な知識を持っていて、何を避けるべきか、何がそうでないかを知っています。より多くのユーザーが、WordPressコアがどのように機能するのかわかりません。

単にテーマをダウンロードしてプラグインをインストールするだけで、必要なことを実行したり、チュートリアルからコードをコピーしたりするだけです。関連記事が1本の記事にまとめられている、よく書かれていないプラグインをインストールしたとします。彼らはそれを自分で整理することができるでしょうか、それとも彼らはこの問題についてテーマ作者にEメールを書くのでしょうか、それともこのサイトに質問を投稿するのでしょうか。

私の質問: $postのようなグローバルがそれほど信頼できないときに他のインポートされたコードによって引き起こされるそのような問題からどのようにあなたは保護することができますか?私たちは$postのようなグローバルを使うべきですか?代替案は何ですか?

結論を出す前にここで頭を共有しておきます。グローバルがメインのクエリの$postにリセットされるようにするために、$postを使う前にwp_reset_postdata()またはwp_reset_query()を使うことを考えました。 。しかし、他の誰かが自分のプラグインを正しくコーディングしていないために、なぜ私のテーマ内のコードを膨らませる必要があるのでしょうか。また、誰かがカスタムクエリを正しくリセットした場合、この操作は2回不要に実行されますが、これは良くありません。

私が考えた2番目の方法は、$wp_queryを使用してからその方法を使用することです。$wp_query->postのようなものです。

これについてのどんな考えでも感謝されるでしょう。

21
Pieter Goosen

some codeが壊れないことを決して確実にすることはできません your code 何もありません あなたはそれを防ぐためにすることができます。特にWordPressでは、 すべて はグローバルです。

そうは言っても、グローバル$postは最もよく使われるグローバル変数の1つなので、特別な care を使うにするといいでしょう。

私のコードでは、グローバル$postに直接アクセスすることはめったにありません。

singular contestにいるとき、私はget_queried_object()を使い、通常$postが有効なWP_Postインスタンスであるかどうかチェックします:

$post = get_queried_object();

if ( ! $post instanceof \WP_Post ) {
   die( 'What the f**k?!' );
}

$postに直接アクセスするというまれなケースでも、私はそのチェックをします。

一部のコードでquery_postsを使用している場合はget_queried_object()が予期しない値を返すことを検討してください。ただし、query_postsに依存しているコードを使用している場合は、サイトが壊れた場合に値します。

さらに、いくつかの条件が予想される場合は、それらを確認します。特定の投稿タイプまたは特定のステータス。

もっとチェックが必要で、もっと多くの場所で、それらを実行する関数を作成します。

function get_global_post() {
    global $post;
    if ( 
        ! $post instanceof \WP_Post
        || ! $post->post_type === 'mycpt'
        || ! in_array( $post->post_status, array( 'publish', 'private' ), true ) 
    ) {
        return false;
    }
    return $post;
}

$mypost = get_global_post();

if ( ! $mypost ) {
      die( 'What the f**k?!' );
}

カスタムクエリの中でループしているときにthe_post()を呼び出すとpostオブジェクトがリセットされるので問題ないはずです。それから、カスタムクエリの後にwp_reset_postdata()を呼び出すのは私の責任です。もちろん、それを行います。

16
gmazzap