do_action and hook methods

时间:2016-06-18 作者:Ptzhub

我试图理解钩子方法在WordPress中是如何工作的。我知道当do_action WP查找所有注册的侦听器,并根据设置的优先级调用它们。

WordPress core如何在不同的文件中收集所有注册的钩子方法?例如,我声明add_action 对于wp_head 在我的页脚中。它会被执行吗?所以WordPress似乎应该收集所有文件上迭代的所有数据?

请解释一下。

2 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

你在这里的类比部分正确,但不完整:

我知道当调用do\\u action时,wp会查找所有注册的侦听器,并根据设置的优先级调用它们。

你需要考虑打电话时会发生什么add_action. WordPress从不搜索add_action 语句,它在列表中有这些语句。当你打电话的时候add_action, 它会更新回调列表,以便在该操作发生时调用。

考虑到这一点,使用事件类比更有用。

  • do_action( \'init\' ) <启动“初始化”操作add_action(\'init\', \'myfunction\' ) init 事件发生,呼叫myfunction
  • function myfunction() {} init 事件发生了
事件类比在理解动作和过滤器如何工作时非常有帮助,因为当你不了解与时间相关的内容时,会发生一整类问题。

让我们以您的呼叫为例add_action 在页脚中wp_head 行动wp_head 在以下情况下激发wp_head() 调用,这应该发生在<header> 标签。如果我们尝试在页脚中添加一个操作,那么它将被添加,下次wp_head() 被称为它会开火。但是wp_head 已经接到电话了,太晚了。这就像在派对结束后问孩子“记得在派对前收拾好你的包”。

考虑到这一点,我有一些一般规则和建议,可以作为更易维护代码的启发:

将所有代码放在触发事件的函数中。init, after_theme_setup, wp_head, 和admin_init 应该涵盖大部分内容,钩子或过滤器之外的唯一代码是模板文件,初始add_action 调用不在模板中添加筛选器和挂钩,请在中进行functions.php 或者插件,或者如果这些文件使用includerequire includes文件夹的语句在某些情况下,您可能希望打破这些规则,通常是为了在保存内容时防止递归等,但这些应该是罕见的例外。进行实验,看看什么是有效的look at this post that shows which actions fire when, and what\'s safe to use at those times

最后一点,动作和过滤器是一样的。从内部来看,他们的待遇是一样的,但如果你想让事情顺利进行,就有一些重要的区别:

操作会做一些事情过滤器会修改事情操作不需要返回任何东西过滤器会将要“过滤”的内容作为第一个参数传递,并且总是返回它或修改的版本过滤器被称为很多,所以永远不要在过滤器中做繁重的工作,这会大大降低速度,只需修改,工作就是行动的目的。小心挂接转换和转义筛选器,这可能是危险的,并且对性能有重大影响,因为这些是最常用的筛选器。有一个特别危险的行动/筛选器称为all, 这将激发每个过滤器和挂钩。有时对调试有用,但我建议改用query monitor之类的插件

SO网友:cjbj

你所有的行动都属于你functions.php, 假设您正在构建一个主题。在这里,您可以向模板中的某些事件添加操作。

现在,一旦读到functions.php WP有一个在主题模板的特定点上应该采取的行动列表。有几个预定义的动作挂钩,例如wp_head()wp_footer(), 它们是do_action(\'wp_head\')do_action(\'wp_footer\'). 它们是被定义的,因此插件有标准的位置,可以在其中添加操作。您还可以使用定义自己的动作挂钩do_action.

例如,如果您想在每篇文章的末尾添加相同的图像,您可以在functions.php 以下操作:

add_action (\'my_post_image\', \'generate_my_post_image\');
function generate_my_post_image () {
    echo \'<img src="path_to_my_image">\';
    }
然后在你的index.php 您可以:

while (have_posts()) {
    ... generate your post ...
    do_action (\'my_post_image\');
    }