私は今何時間もこの問題に苦しんでいます、何が起こっているかはdbに値を挿入する前のどこかで、このアクションが呼ばれているということです。
do_action_ref_array('h5p_alter_user_result', array(&$data, $result_id, $content_id, $user_id));
次に示すのは、値とその設定方法です。
$user_id = get_current_user_id();
$result_id = $wpdb->get_var($wpdb->prepare(
"SELECT id
FROM {$wpdb->prefix}h5p_results
WHERE user_id = %d
AND content_id = %d",
$user_id,
$content_id
));
$table = $wpdb->prefix . 'h5p_results';
$data = array(
'score' => filter_input(INPUT_POST, 'score', FILTER_VALIDATE_INT),
'max_score' => filter_input(INPUT_POST, 'maxScore', FILTER_VALIDATE_INT),
'opened' => filter_input(INPUT_POST, 'opened', FILTER_VALIDATE_INT),
'finished' => filter_input(INPUT_POST, 'finished', FILTER_VALIDATE_INT),
'time' => filter_input(INPUT_POST, 'time', FILTER_VALIDATE_INT)
);
if ($data['time'] === NULL) {
$data['time'] = 0;
}
$format = array(
'%d',
'%d',
'%d',
'%d',
'%d'
);
$content_id = 1;
私がやろうとしているのは、データベースに保存される前にこれらの値を変更したいということです(そしてこのフックはデータベースに保存される前に呼び出されます)。
add_action( 'h5p_alter_user_result', 'diff_test_callback' );
function diff_test_callback($args)
{
global $wpdb;
$user_id = 1;
$result_id = 1;
$content_id = 1;
$table = $wpdb->prefix . 'h5p_results';
$data = array(
'score' => 777,
'max_score' => 189,
'opened' => 333,
'finished' => 222,
'time' => 111
);
if ($data['time'] === NULL) {
$data['time'] = 0;
}
$args = array( $data, $result_id, $content_id, $user_id );
return $args;
}
しかし、値は変更されていません、何か問題がありますか?
フックを使用して変数または任意の値を変更したい場合は、(アクションフックの代わりに)フィルタフックを使用してそれを行うのが最善です。内部的にはアクションとフィルタの実装はほぼ同じですが、規約は次のとおりです。
アクションフックでは、コールバック関数の中で何かをしたり、エコー出力したりしますが、何も返しませんし、そのコールバック関数の範囲外の引数も変更しません。
フィルタフックを使用すると、コールバック関数から値を返し、それをどこかで使用するか、またはコールバック関数の外部の変数に割り当てることができます。
そのため、apply_filters
CODEを次のように使用してください。
// using apply_filters() instead of the following do_action_ref_array() line
// do_action_ref_array( 'h5p_alter_user_result', array( &$data, $result_id, $content_id, $user_id ) );
$data = apply_filters( 'h5p_alter_user_result', $data, $result_id, $content_id, $user_id );
これと一致させるには、add_filter
と次のようなコールバック関数を使用します。
// Declare number of parameters to be passed in add_filter.
// According to our apply_filters() call,
// we expect 4 parameters to be passed to the callback function
add_filter( 'h5p_alter_user_result', 'diff_test_callback', 10, 4 );
function diff_test_callback( $data, $result_id, $content_id, $user_id ) {
// do something with $data
// remember: manipulation of $data doesn't have any affect
// outside of this function
// So we need this return
return $data;
}
do_action_ref_array
の問題:あなたのdo_action_ref_array
呼び出しから、あなたが参照として$data
を渡そうとしているように見えます:
do_action_ref_array( 'h5p_alter_user_result', array( &$data, $result_id, $content_id, $user_id ) );
ただし、PHP 5.4以降、この動作は変更されました。 do_action_ref_array
は、引数の参照をコールバック関数に渡しません。代わりに、コピーを渡します。
また、PHP 5.4以降、参照による呼び出し時間の経過は受け付けられません。そのため、上記のコードに示すようにapply_filters
メソッドを使用するのが最善です。
はお勧めできませんが、配列内の関数パラメータとして参照ポインタを使用して実行することができます。このような:
// add_action without passing the number of parameters
add_action( 'h5p_alter_user_result', 'diff_test_callback' );
// callback function implementation with reference pointer `&`
// for parameters you are expecting with reference
function diff_test_callback( $args ) {
// we need the reference of $data, so using & operator here.
$data = &$args[0];
$result_id = $args[1];
$content_id = $args[2];
$user_id = $args[3];
// now making changes to $data
// will be reflected outside the scope of this function
// no return is necessary
}
// at the time of executing the action,
// create the $args array with reference to $data
$args = array( &$data, $result_id, $content_id, $user_id );
do_action_ref_array( 'h5p_alter_user_result', array( $args ) );
警告:繰り返しますが、
do_action_ref_array
メソッドは注意深く参照を処理すれば機能しますが、このシナリオではfilter hookメソッドを使用することを強く推奨します。