WordPress 钩子中的匿名函数

Posted

技术标签:

【中文标题】WordPress 钩子中的匿名函数【英文标题】:Anonymous functions in WordPress hooks 【发布时间】:2015-09-23 06:43:31 【问题描述】:

WordPress 钩子有两种使用方式:

    使用回调函数名称和适当的函数

    add_action( 'action_name', 'callback_function_name' );
    function callback_function_name() 
        // do something
    
    

    使用匿名函数(闭包)

    add_action( 'action_name', function() 
        // do something
     );
    

WordPress有什么区别用什么方式?什么是首选方式,为什么?

【问题讨论】:

我不是 WP 专家,但我见过的大多数钩子都不使用 annon 函数。然而无论如何。这并不是说使用它们有什么问题。我想这可以归结为到目前为止你在项目中是如何完成的。坚持一个或另一个,保持一致。 【参考方案1】:

匿名函数的缺点是您无法使用remove_action 删除操作。

重要提示:要删除挂钩,添加挂钩时$function_to_remove$priority 参数必须匹配。这适用于过滤器和操作。删除失败不会发出警告。

因为你没有定义function_to_remove,所以你不能删除它。

所以你不应该在其他人可能想要覆盖的插件或主题中使用它。

【讨论】:

您甚至可以使用remove_all_actions()remove_all_filters() 删除匿名挂钩。但即便如此,我同意在 WordPress 中定义常规函数是首选模式。 关于主题的有趣文章:inpsyde.com/en/remove-wordpress-hooks【参考方案2】:

使用闭包的好处是保持全局命名空间干净,因为您不必先创建全局函数来作为回调传递。

add_action('admin_init', function () 
    // some code...
);

我个人更喜欢使用闭包作为回调,除非

您希望能够移除回调 回调函数需要多次使用 您需要支持旧 php 版本(低于 5.3)

类中的闭包

闭包也可以在类中有益

class SomeClass

    public function __construct()
    
        add_action('wp_head', function () 
            $this->addSomeStyling();
        );
    

    protected function addSomeStyling()
    
        echo '<style> body  color: #999;  </style>';
    

通常需要将回调方法设为public,但在这种情况下,您也可以将它们设为privateprotected

此解决方案仅适用于 PHP 5.4+。为了使其也适用于 PHP 5.3,您需要将 $this 对象引用显式传递给闭包,例如:

    public function __construct()
    
        $self = $this;

        add_action('wp_head', function () use ($self) 
            $self->addSomeStyling();
        );
    

【讨论】:

完全不同意在钩子中使用闭包。您永远无法知道其他人如何处理钩子。例如,一个人可能需要移除你的钩子并使用他/她卡住的闭包。 在您不操作公共 API 接口的上下文中使用闭包是一件好事。 您也可以通过其他方式使用命名空间函数:add_action('acf/init', 'child_theme\load_content_types'); 您可以在namespace child_theme; 下方使用它。 忠告,当您使用匿名函数进行挂钩回调时,您实际上使您的代码无法测试。甚至无法检查 has_action 是否有此类回调,更不用说覆盖代码了。但代码覆盖率完全不同...... 刚刚看到这篇文章,我真的只是想强调一下 cmets 对此答案的陈述。正如@TeeDeeJee 的回答中所述,如果您的插件/主题应该被其他人使用/修改,您应该避免这种情况。但是假设您自己开发了一个主要的自定义插件,您只将其用于您自己的网站,并且该插件的正常运行对您的网站至关重要。在这些情况下,让通过匿名函数从钩子中删除(重要)插件回调变得更加困难真的是一个坏主意吗? ....【参考方案3】:

更准确地说,我想从current wordpress docs 中添加这个;实际演示这如何依赖于用例:

“为什么我们在这里使用命名函数 [作为 ajax 动作钩子的回调] [...]?因为 PHP 最近才支持闭包。[...] 因为有些人可能仍在运行旧版本对于 PHP,我们总是使用命名函数以获得最大的兼容性。如果您有最新的 PHP 版本并且只是为自己的安装进行开发,如果您愿意,请继续使用闭包。"

【讨论】:

以上是关于WordPress 钩子中的匿名函数的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中的匿名函数立即执行函数和闭包

PHP中的闭包和匿名函数

浅析PHP中的闭包和匿名函数

python之匿名函数以及在内置函数中的使用

Python中的匿名函数——lambda函数

Elixir 中的命名函数和匿名函数有啥区别?