外部変数をフィルター/アクションに渡す方法


11

サードパーティのプラグインによって提供されるフィルターにカスタムデータを渡す必要があることに気づきました。これを行うために私が見た方法はすべて非常に複雑で、頭を回すのが困難です。

この例を見てみましょう:

$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

$score変数をどのように渡すことができadd_score_to_title()ますか?

私がやったことは、グローバル$wpオブジェクトに変数を追加することでした。だからあなたはこれで終わります:

global $wp;
$score = 42; //Some crazy calculation I don't want to repeat.
$wp->some_random_name_for_score = $score;

function add_score_to_title($title) {
    global $wp;
    $score = $wp->some_random_name_for_score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

汚れた?多分。簡単?うん!この手法の欠点はありますか?議論してください。

更新 ここに問題の完全なコードがあります-> http://pastebin.com/fkSXY04m


その関数内で「クレイジーな計算」を行うだけです...
onetrickpony

私の簡単な例から理解するのはおそらく難しいでしょう。$ score変数は、そのテンプレート全体で使用されます。一度計算して、ページタイトルを変更するためのフィルターのコールバックである関数にその値を渡します。このフィルターはAll In One SEO Packで使用されます。計算を複数回実行することは望ましくありません。
kingkool68

次に、グローバル状態の導入を必要としないソリューションが必要な場合は、さらにコードを投稿する必要があります(これは決して必要ではありません)。
onetrickpony

テンプレートファイルの完全なコードは次のとおりです。$score物事の配列をループして変数をインクリメントすることで計算されます。 pastebin.com/fkSXY04m
kingkool68

回答:


10

少なくとも2つのオプションがあります。

  1. 目的の変数をグローバル化し、コールバック内で参照します
  2. スコア計算ロジックを関数でラップし、コールバック内で参照します

変数をグローバル化する

<?php
global $score;
$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    global $score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

スコア計算をラップする

フィルターのスコア計算のみが必要な場合は、ロジックをコールバック自体にプルします。

<?php
function add_score_to_title($title) {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
        $order = $question->order;

        if( $order >= 100 ) {
            break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

さらに良いことに、スコア計算を独自の関数でラップし、コールバック内でその関数を呼び出すことができます。

<?php
function wpse48677_get_score() {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
    $order = $question->order;

    if( $order >= 100 ) {
        break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;
    $output['score'] = $score;
    $output['total_questions'] = $total_questions;

    return $output;
}

function add_score_to_title($title) {

    $score_results = wpse48677_get_score();

    $score = $score_results['score'];

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

$_POSTオブジェクトの参照に問題がある場合は、クエリ変数を登録し、get_query_var()内部的に使用してデータを取得することもできます。

function add_score_query_vars( $query_vars ) {
    $query_vars[] = 'Q';

    return $query_vars;
}
add_filter( 'query_vars', 'add_score_query_vars' );

これで、$_POST['Q']と置き換えることができますget_query_var('Q')


これは、apply_filtersによって関数に渡される引数の数とは関係ありません...
onetrickpony

変数のグローバル化について言及した方法#1を試してみました。動作しません。コールバック関数に渡される変数を制御できないため、受け入れられたargsパラメーターも役に立ちません。
kingkool68

ごめんなさい、正解でした。$score最初に計算し、それをグローバル化しました。うまくいかなかったのも無理はありません。ありがとうございました!
kingkool68 2012

-1。最初のオプションはグローバル状態の変数を公開し、2番目のオプションは機能しません...
onetrickpony 2012

1
グローバルは悪だ」?ほんと?次に、WordPressのコード全体を作成する方がよいでしょう。なぜなら、かなりの数のグローバル変数に依存しているからです
チップベネット

3
function add_score_to_title($title = false) {
  static $score = false;

  if($score === false){
    // do calc
  }

  // plugin call (filter)   
  if($title !== false)
    return 'Quiz Results (' . $score . ') - ' . $title;

  // your call
  return $score;
}

スコアを取得するには、スクリプトの任意の場所で関数を呼び出します。スコアは1回だけ計算されます。

匿名関数を使用する別の方法:

// do the calc
$score = 'xxx';

add_filter('aioseop_title_single', function($title) use($score){
  return 'Quiz Results (' . $score . ') - ' . $title;  
});

3
匿名関数は、add_filter()またはで使用しないでくださいadd_action()。から削除することはできませんremove_function()
チップベネット

これは、プラグイン/テーマによって追加されたフィルターではなく、主に組み込みフィルターを削除するために使用されるremove_filterを意味します...
onetrickpony

1
はい; 申し訳ありません:remove_filter()remove_action()。そして、削除するプラグイン/テーマフィルタは合理的にできないようにする必要がありという理由はありません:スタイルシートのエンキュー、子供のテーマ、プラグインなどをオーバーライド
チップベネット

0

次の例では、$my_calculationグローバルスコープの変数を確認していますが、ローカル関数内からglobal $my_calculation、グローバルスコープの変数にアクセスするために宣言する必要があります。

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

これはそれを実行する方法の1つにすぎず、見栄えが良いようです。これでうまくいきますか?


これは彼がすでに持っているものとどう違うのですか?
onetrickpony

「グローバル」の宣言が少なくなります。彼の2番目の例を見ると、彼はgloabl $ wpを2回宣言しています!
アダム

また、機能しません。これは私が最初に試したものです。
kingkool68 2012

あなたはすることができますprintまたはechoあなたの結果はあなたの関数が実際のフィルタに渡す前に動作していることを確実にするために?
アダム

おっとっと!グローバリゼーション$scoreは確かに機能します。私は間違えて$score最初に設定し、次にグローバル化しましたが、明らかに機能しません。$score最初にグローバル化してから適切な方法で実行し、次に値を指定すると、期待どおりに機能します。皆さんありがとう。
kingkool68 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.