do_actionと戻り値の取得方法は?


10

したがって、次のシナリオがあります。

データベースからログを削除するアクションを追加します。

add_action( 'myplugin_clean_logs', array( 'MyPlugin_Logs', 'clean_logs' ) );

今、私はこのアクションを定期的に実行したいと思います:

wp_schedule_event( current_time( 'timestamp' ), 'daily', 'myplugin_clean_logs' );

そしてそれを手動で実行します:

do_action( 'myplugin_clean_logs' );

このメソッドMyPlugin_Logs::clean_logsは影響を受けた行の数を返すか、何かが他の方向に進んだ場合はfalseを返します。

次に、削除された行の数を表示します。私はこのようなものを想像します:

$affected_rows = do_action( 'myplugin_clean_logs' );
echo $affected_rows . ' entries have been deleted.';

しかし、do_action値を返さないので、戻り値を取得する方法がわかりません。

手動実行でメソッドを直接実行する必要がありますが、スケジュールイベントのアクションを使用する必要がありますか?


1
あなたはスケジュールされたイベントで何もエコーしたくないので、はい、私は手動で直接メソッドを実行します(管理者がこれをトリガーし、出力を表示したいと思います)。
Tim Malone、

回答:


13

すばらしいのは、フィルターはアクションと同じで、値を返すだけなので、フィルターとして設定するだけです。

add_filter( 'myplugin_clean_logs', array( 'MyPlugin_Logs', 'clean_logs' ) );

次に、次のようなもの:

$affected_rows = '';
$affected_rows = apply_filters( 'myplugin_clean_logs', $affected_rows );

$affected_rowsclean_logs()(およびフックした他の関数にmyplugin_clean_logs)渡して、戻り値をに割り当て$affected_rowsます。


4
これはソフトウェアを開発するのではなく、コードをハッキングするため、反対票を投じました。アクションがフィルターのサブセットにすぎない場合、アクションは必要ありませんでした。Cronはそのため値を渡すことができません。バグのあるコアコードでそのようなシェミガンを実行できる場合でも、フィルターとしてフックする必要はありません:)
Mark

1
ポイントを取る。私は2つの異なる目的があることを理解していますが、ここでコアコードを見ると、全体do_action()は手の込んだハックにすぎませんapply_filters():)
Caspar

コアの悪いデザインだけではなく、このような疑問につながる混乱につながるものもあります
Mark Kaplun

1
私たちが持っているもので作業する必要があるので、マークの視点を理解していますが、これは正当な答えだとまだ思います- もちろん、コアがこのアプローチを将来変更しない限り、後方互換性の問題が大きいため、そうは思われません紹介します。
Tim Malone

3
ありがとう、@ TimMalone。@ mark-kaplunの異論に感謝します。私の回答ではdo_action()do_action()意図に合わせてソリューションを設計する方法ではなく、値を返さないようにする方法を説明しています。誰かが彼の求めていることを実行できる場合、その答えは受け入れられる答えになるに値します。私の最初の考えは、フックされたメソッド(OPがこのプラグインのOOPデザインを使用していると想定)をその結果をプラグインクラスの保護されたプロパティにドロップし、それを後で取得するためのクイックゲッターを作成することです。しかし、それはアイデアのワイルドな髪です。
Caspar

-1

この関数を使用したことがなく、テストもしていませんが、機能するでしょうか? do_action_ref_array()

function myplugin_clean_logs_fn() {
    $args = array(
        'param1'        => 'val1',
        'param2'        => 'val2',
        'affected_rows' => 0,
    );
    do_action_ref_array( 'myplugin_clean_logs', &$args );
    return $args['affected_rows'];
}

// CALL IT
$affected_rows = my_plugin_clean_logs();
echo $affected_rows .' entr'. ($args['affected_rows']*1===1?'y':'ies') .' deleted.';

// SCHEDULE IT
add_action('myplugin_clean_logs_call_fn', 'myplugin_clean_logs_fn');
wp_schedule_event( current_time( 'timestamp' ), 'daily', 'myplugin_clean_logs_call_fn' );

// A SAMPLE FILTER
add_action('myplugin_clean_logs', function($args) {
    // Cleaning process
    // For each log affected, increment $args['affected_rows'] accordingly
}, 10, 3);

それがうまくいかない場合は、Casparが提案するようなものをフィルターに掛けてみませんか?つまり、それがフィルターの目的であり、この場合、影響を受ける行の数がフィルターされます。(私は古いMortCoreを見逃しています。単一の3つのパラメーター関数で戻り値、参照渡し、および引数を処理した方法を覚えている人はいますか?)


参照によって値を渡したり変更したりすることは本当に悪い習慣なので、これは恐ろしい答えです。正直なところ、この回答は実際には質問のコンテキストでは価値を提供しないため、削除するかコメントに変更する必要があります。さらに、フックで無名関数を使用すると、フックを解除できなくなるため、これも悪い習慣です。
ハイブリッドWeb開発

上記と同じ理由で、これは推奨される方法ではないことに同意します。何らかの理由でアクションから戻り値を取得する必要があり、素早くダーティなものが必要な場合は、Casparsソリューションをお勧めします。ライフサイクルが先行するものを開発している場合は、より堅牢な方法を探します。考えてみると、管理者の通知はどうですか?developer.wordpress.org/reference/hooks/admin_notices
jgangso
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.