在不使用Function_Existes()的情况下通过短路来设置要覆盖的函数吗?

时间:2017-06-28 作者:GreatBlakes

几年前我read an article about short-circuiting functions 具有apply_filters() 而不是通过function_exists(). 我喜欢这个想法,因为它是多么灵活——我不受什么时候可以覆盖一个函数(插件、子主题、父主题)、覆盖频率或命名约定的限制。基于这种心态,我编写了我的主题,以允许许多功能以这种方式短路。

用于比较:

Pluggable Function Override

if ( !function_exists(\'xyz_print_name\') ){
    function xyz_print_name($name){
        //Do stuff here
    }
}

Short-circuited Function Override

function xyz_print_name($name){
    $override = apply_filters(\'xyz_pre_print_name\', null, $name); //Notice $name is a single parameter, so this works no problem. See below for issues with multiple parameters when I split it into first and last name.
    if ( isset($override) ){return;}

    //Do stuff here
}
我可以这样覆盖它:

add_filter(\'xyz_pre_print_name\', \'__return_empty_string\');
或者我可以这样重写:

add_filter(\'xyz_pre_print_name\', \'abc_print_name\');
function abc_print_name($name){
    //Do my own stuff here
    return true;
}
这是非常棒的,直到我遇到了过去几个月断断续续困扰我的问题。。。

我可以很容易地重写没有参数甚至只有一个参数的函数,但两个或多个参数将通过活动扳手进入所有对象。

我也不太明白为什么。我想这和second parameter of apply_filters() itself: $value

因为我没有传递值,所以我分配它false, 并使用实际$arg1, $arg2, 等参数。但是,当我编写实际的覆盖函数时,I need to include a null value in the declaration to accommodate it. 我觉得这是一个草率的代码:

add_filter(\'xyz_pre_print_name\', \'abc_print_name\', 10, 3); //I must pass 3 parameters here (instead of the 2 I need to account for the extra $null parameter)
function abc_print_name($null, $first_name, $last_name){ //Notice here I need to pass $null as the first parameter
    //Do stuff here
}
相反,我可以这样做,但我注意到it breaks some of my functions (根据WordPress Codex,技术上是不正确的,因为我滥用了$value 参数):

//...
$override = apply_filters(\'xyz_pre_print_name\', $first_name, $last_name);
//...

add_filter(\'xyz_pre_print_name\', \'abc_print_name\', 10, 2);
function abc_print_name($first_name, $last_name){ //Notice $first_name is being passed as the $value parameter of the filter- which is wrong
    //Do my own stuff here
}
最后一个提示,如果我将覆盖切换为使用do_action() 而不是apply_filter() 它在参数之前没有额外的参数,除了我无法检测到是否使用了覆盖钩子之外,一切都很好,因此覆盖函数和我的原始函数都会运行。

哎哟,这是一个很长的问题。TL;DR WordPress中是否还有其他人短路功能?我想我甚至在WordPress核心中也看到了一些关于它的讨论。如果是,你是怎么做的?你遇到过类似的问题吗?

我很难找到其他人尝试这种方法,所以我很感激有任何见解。我只是不想放弃这个方法。。。

Edit: 要指定我的问题:

是否有更好的方法允许功能短路,以便$null 使用时不需要使用参数?我还在上面的代码片段中添加了注释,以说明我在每个代码片段中指定的内容。

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

首先,请避免这样做echo 在过滤器上。原因过滤器的设计方式不适合处理echo. 它们被设计为获取参数或输入,并在挂钩函数内修改或操作,然后将其发送回父函数。如果这个过滤器不返回数据,那么就有很大的机会打破WordPress 生命周期

其次,两者之间存在显著差异do_actionapply_filters. do_action 定义了一个标志,您可以在其中添加一些要执行的函数。这有点像是在这一点上添加了一些额外的函数来执行。哪里什么apply_filters does是定义一个标志,从中可以获取一些数据,然后修改或操作它,然后将其返回给父级。这样您就可以操纵数据。

最后谈谈你的观点,使用$null 价值如果你读了apply_filters 文档然后您可以看到,第一个参数是我们需要修改的值,其他变量是附加参数或参数。因此,要首先修改值,需要在函数中获取值。And as it is required, so you can\'t escape it. 而且,在将值和参数输入到挂钩函数时,不能破坏它们的顺序,因为它将输入值和参数作为顺序,而不是名称。

希望以上帮助。

结束

相关推荐

WordPress Plugins won't save

我有一个WordPress网站,我刚刚接管了一个客户,因此我没有能力与以前的网站管理员/开发人员交谈。该网站使用的是YOOtheme对Subway稍加修改的版本。为了更新插件位置,Subway的一部分有“小部件选项”。我无法更改外观或小部件显示的页面,因为我无法保存任何内容。它看起来像已保存,但没有保存,或者您会在保存按钮旁边看到“加载循环”,它一直在运行。Things to note:<WordPress和插件是最新的。在我们转移到新服务器之前,插件是可更新的。新服务器有一个max\\u inpu