RTrouble将参数传递给行动

时间:2021-02-09 作者:Daveh0

我知道有几个帖子是关于这个话题的。我已经关注了其中的许多内容以及网络上的其他资源,并认为我已经记下来了,但它似乎没有起作用。在我的例子中,有两个函数连接到两个需要相同数据的单独操作。

$data = array(\'red\', \'green\', \'blue\');

do_action(\'use_colors_here\', $data);
add_action(\'wp_body_open\', \'use_colors_here\', 10, 1); 
function use_colors_here($data) {
  $out = \'<h1>Colors</h1>\';
  $out .= \'<p>Color 1: \' . $data[1] . \'</p>\';
  $out .= \'<p>Color 2: \' . $data[2] . \'</p>\';

  echo $out;
}

do_action(\'use_colors_there\', $data);
add_action(\'wp_enqueue_scripts\', \'use_colors_there\', 10, 1); 
function use_colors_there($data) {
  wp_enqueue_script(\'color-script-1\', get_stylesheet_directory_uri() . \'/js/colors_\' . $data[1] . \'.js\');
  wp_enqueue_script(\'color-script-2\', get_stylesheet_directory_uri() . \'/js/colors_\' . $data[2] . \'.js\');
}
预期的行为用于的值$data[1]$data[2] (分别为绿色和蓝色)可由两个功能访问并打印在标记中,每个功能负责添加到页面中。不幸地$data 无法在函数中访问,我最终得到如下标记:

<h1>Colors</h1>
<p>Color 1: </p>
<p>Color 2: </p>
我做错了什么?

更新仔细阅读后,我发现必须使用钩子而不是函数名作为的第一个参数do_action. 所以我把它改成:

do_action(\'wp_body_open\', $data);
它似乎正在发挥作用。

最终代码(使用接受的答案)

function get_component_config() {
  return [\'red\', \'green\', \'blue\'];
}

add_action(\'wp_body_open\', \'use_colors_here\'); 
function use_colors_here() {
  $data = get_component_config();
  $out = \'<h1>Colors</h1>\';
  $out .= \'<p>Color 1: \' . $data[1] . \'</p>\';
  $out .= \'<p>Color 2: \' . $data[2] . \'</p>\';

  echo $out;
}

add_action(\'wp_enqueue_scripts\', \'use_colors_there\'); 
function use_colors_there() {
    $data = get_component_config();
    wp_enqueue_script(\'color-script-1\', get_stylesheet_directory_uri() . \'/js/colors_\' . $data[1] . \'.js\');
    wp_enqueue_script(\'color-script-2\', get_stylesheet_directory_uri() . \'/js/colors_\' . $data[2] . \'.js\');
}

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

您有一个名为use_colors_here 然后你用do_action( \'use_colors_here\', $data ), 但我看不出你在哪里打电话add_action() 为了那个钩子?

我是说do_action()add_action() 应这样使用:

// This adds a callback to the use_colors_here hook.
add_action( \'use_colors_here\', \'some_function\' );

// And this is the callback which accepts one parameter from the use_colors_here hook.
function some_function( $data ) {
    var_dump( $data );
}

// And this do_action() executes the above callback (and other callbacks added to the
// `use_colors_here` hook).
$data = array( \'red\', \'green\', \'blue\' );
do_action( \'use_colors_here\', $data );

更新(修订)

我发现我必须使用钩子而不是函数名作为do_action

是的,没错,第一个参数do_action() 实际上是钩子名称,而第二个和其余的参数是传递给钩子回调的参数-但是对于两个或多个参数,需要使用第四个参数add_action() 指定回调接受的参数数。

// This fires the some_hook hook which has two parameters.
do_action( \'some_hook\', \'param 1\', \'param 2\' );

// So when adding your action, if you want (to access) both the above parameters
// from your callback, then you must set the 4th parameter below to 2.
add_action( \'some_hook\', \'some_function\', 10, 2 );

function some_function( $param1, $param2 ) {
    var_dump( $param1, $param2 );
}
do_action() (尽管间接)实际使用call_user_func_array() 运行特定(操作)挂钩的操作,或运行注册在该挂钩上运行的回调call_user_func_array() 工作,那么你也会明白do_action() 作品

function my_callback( $foo, $bar ) {
    var_dump( $foo, $bar, __FUNCTION__ );
}

$data = \'using call_user_func_array()\';
// this calls my_callback() directly
call_user_func_array( \'my_callback\', array( $data, \'second param\' ) );

add_action( \'hook_name\', \'my_callback\', 10, 2 );
$data = \'using do_action()\';
// but this fires the "event"/hook named hook_name and then it calls
// my_callback() indirectly via call_user_func_array()
// i.e. it calls call_user_func_array( \'my_callback\', array( $data, \'yay, it works!\' ) )
do_action( \'hook_name\', $data, \'yay, it works!\' );
我只需要能够访问$data 从我的2个功能中,use_colors_hereuse_color_there

那么你做对了,也就是说do_action(\'wp_body_open\', $data), 这个$data 将传递给您的2个函数(以及钩子的所有其他操作/回调)。

但不打电话do_action() 手动且不使用global 关键字或偶数$GLOBALS,访问$data 变量是通过使用闭包;然而,缺点是几乎不可能使用remove_action() — 因为闭包是匿名函数,所以在删除操作时使用什么名称?

add_action( \'some_hook\', \'some_function\', 10, 2 );
// that can be easily removed like so:
remove_action( \'some_hook\', \'some_function\', 10 );

$data = array( \'red\', \'green\', \'blue\' );
add_action( \'some_hook\', function () use ( $data ) {
    var_dump( $data );
} );
// now with that one, how do we remove it?
//remove_action( \'some_hook\', ??, 10 );
因此,如果您只想访问$data, 然后可以使用一个自定义函数返回数据:

function get_colors() {
    return array( \'red\', \'green\', \'blue\' );
}

add_action( \'wp_body_open\', \'use_colors_here\' );
function use_colors_here() {
    $data = get_colors();
    var_dump( $data );
}
我想最好把所有东西都放进去functions.php而不是向header.php... 只是为了组织目的。

是的(虽然不完全是“一切”),我也这么想。但在我的原文中;更新(&Q);第节,我只是说你可以(或者如果你可以)在钩子被触发后显式调用你的动作。一、 e。

// Let\'s say you define $data here. (in same file or block of code)
$data = array( \'red\', \'green\', \'blue\' );

// So instead of..
do_action( \'wp_body_open\', $data );

// You can do..
wp_body_open(); // this fires the wp_body_open hook
use_colors_here( $data );

// But that means, use_colors_here() should no longer be hooked on to the hook.
是否直接在中调用函数header.php 有任何显著的性能优势吗?

不,但直接打电话意味着你可以轻松通过$data 和其他参数。。

否则,对于局部变量,如$data 然后,我们需要使用闭包来访问变量(以及该变量内部或引用的数据)。

相关推荐

为什么WordPress在未登录时会将与管理员相关的脚本(例如,Reaction、ReactDOM、Redux、Hooks、TinyMCE等)放入队列?

为了提高我的网站的性能,我注意到Wordpress在前端加入了许多与管理相关的脚本和样式表。我想知道我怎样才能阻止这一切的发生。。。我正在考虑将所有的违规行为都退出队列,但我的服务器响应时间会稍微慢一点。是否有一种经过测试的方法可以做到这一点?