PHPでのフィルターとフックの実際の動作


21

WordPressでは実際にフィルターとフックはどのように機能しますか?

私は何か高度なことを尋ねています。PHPではどのように実装されていますか?たとえば、さまざまなプラグインからすべてのフックを収集し、それらをコアフックなどに「アタッチ」する方法など。


2
私が知っている限り、PHPには「フック」や「フィルター」はありません。Wordpressには、実行前に他の関数のコールバックを使用する特別な関数があります。
Ofirバルーク


3
@OfirBaruch、私はOPがWordPressでの実装を参照していると確信しており、そのネイティブPHP実装があることを示唆していませんでした。
トム・オージェ

回答:


33

概要

基本的に、フィルターとフックを呼び出す「プラグインAPI」は、次の関数で構成されています。

  1. apply_filters()- 実行する
  2. do_action- 実行する
  3. apply_filters_ref_array()- 実行する
  4. do_action_ref_array()- 実行する
  5. add_filter()- スタックに追加
  6. add_action()- スタックに追加

基本的な内部

全体として、いくつかのグローバル(WordPressの世界では他にあります)が関係しています。

global $wp_filter, $wp_actions, $wp_current_filter, $merged_filters;

最初のもの$wp_filterは、Arrayすべてのフィルター名をサブ配列として保持するグローバルです。これらのサブアレイはそれぞれ、優先アレイの下で呼び出されるコールバックであるサブアレイをさらに保持します。

簡単な詳細

そのため、execute関数が呼び出されると、WordPressはそれらのグローバル配列でその名前のキーを検索します。次に、添付されたコールバックが優先度の後に実行されます。前もって起こる唯一のことは、allフィルターに接続されたコールバックです。

add_actionまたはを使用してコールバックを追加するadd_filterと、WordPressは最初に「一意の」IDを計算して、既に接続されているコールバックを上書きしません。

$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);

次に、コールバックをglobal $wp_filterスタックに追加します。

$wp_filter[ $tag ][ $priority ][ $idx ] = array(
    'function'      => $function_to_add,
    'accepted_args' => $accepted_args
);

メインのサブ配列が$tag(またはアクション/フィルター名)であることがわかると、特定の優先度ですべてが呼び出され、「一意の」コールバック/ ID文字列がキーとして使用されます。

後で、フィルターが呼び出されると($tag/ action- / filter-nameで発生)、配列が検索され、コールバックが呼び出されます。使用call_user_func_arrayしているため、実際にいくつの引数がアタッチされているかは問題ではありません。WordPressはそれを自動的に解決します。

foreach ( (array) current( $wp_filter[ $tag ] ) as $the_ )
{
    call_user_func_array(
        $the_['function'], 
        array_slice(
            $args, 
            0, 
            (int) $the_['accepted_args']
        )
    );
}

3
それは、コールバックを通じて起こっているとして、それが10にそのadd_actionとセット(オプション)(である「優先度」、)とapply_filters()およびデフォルトを使用して、同じフックに複数のコールバックの実行を命令することを忘れないでください
トムオージェ

1
@TomAuger追加のメモや編集を回答に自由に追加してください。
カイザー

5

フックは、WordPressコアファイルといくつかの親テーマファイルの両方に含まれています。ファイル内の特定の場所でコンテンツをフックできます。

例は、WordPressのwp_headフックです。子テーマでこのフックを使用して、その場所にコンテンツを追加できます」

例:

add_action('wp_head', 'add_content_to_head');
function add_content_to_head() {
echo 'Your Content';
}

一部のプレミアムテーマには、子テーマで同じことを行うために使用できるアクションフックも含まれいます。ここに、すべてのアクションフックとそれらがGenesisテーマフレームワークでコンテンツを出力する位置を含むビジュアルマップがあります。

例:

add_action('genesis_header', 'add_content_to_header');
function add_content_to_header() {
echo 'Your Content';
}

Genesisテーマフレームワークでheader.phpファイルを開いた場合、フックは次のようになります。

do_action( 'genesis_header' );

以下は、さまざまな方法で使用できるWordPressフックのリストです。

フィルターを使用すると、既存の関数の出力を変更でき、WordPressコアファイルとGenesisのような親テーマフレームワークの両方に含まれます。

ここだフィルタのリストあなたはジェネシスのデザインフレームワークを使用することができますが

WordPressに含まれるフィルターのリストは次のとおりです。

Genesisのようなテーマフレームワークでフィルターを使用する方法の例を次に示します。

add_filter( 'comment_author_says_text', 'custom_comment_author_says_text' );
function custom_comment_author_says_text() {
return 'author says';
}

上記のコードを子テーマで使用して、作成者がコメントのテキストを言うように変更できます。どのテーマでも機能します。

次に、抜粋の長さを50ワードにカスタマイズする別の例を示します。

add_filter( 'excerpt_length', 'change_excerpt_length' );
function change_excerpt_length($length) {
return 50; 
}

the_excerpt()関数はwp-includes / post-template.phpファイルにあります。

これは次のようなものです。

  function the_excerpt() {
        echo apply_filters('the_excerpt', get_the_excerpt());
}

プラグインでフックとフィルターを使用してまったく同じことを行うこともできます。親テーマまたはWordPressを更新してもコードは失われません。

基本的に、フックとフィルターを使用すると、WordPressのコアファイルまたは親テーマファイルを編集せずに、WordPressと親テーマの両方をカスタマイズおよび変更できます。

親テーマのテンプレートファイルを編集する必要がないため、親テーマフレームワークにフックとフィルターが含まれていると、子テーマのカスタマイズが非常に簡単になります。これにより、テーマも安全に変更できます。


2
これは、フックとフィルターの一般的な概要です。しかし、OPの質問、つまり、フックがどのように機能し、WordPressがそれらを作成、保存、処理する方法の内部についての質問を完全に見逃していると思います。素晴らしい答え; おそらくWPサイトのチュートリアルにリンクする必要があります。
トム・オージェ

はい、削除します。私は悪いので質問をよく読んでおくべきでしたが、初心者が最初に基本を知っていれば、すでに与えられた答えが理解しやすいと思いました。
ブラッドダルトン

2
ブラッド、この情報もここにあると便利だと思うので、元に戻しました。同意しない場合は、ここで言及/ pingしてください。再度削除します。
カイザー14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.