实现高级Add_*函数包装器

时间:2011-03-05 作者:Rarst

add_action()add_filter() 是主要功能。然而,在某些情况下,再添加一个函数并将其挂接到某个地方,这种方法会变得笨重和不方便。

我为自己确定了几个用例,这些用例可以在add_* 功能。使用单行程序处理比每次都使用额外功能更好的事情。

  1. Add arbitrary filter return. 已经有了__return_* 但它们的定义非常有限。为什么不直接传递过滤器中返回的内容呢。从无数次中保存function return_stuff(){return \'stuff\';}

  2. Replace X with Y in filter. 从无数次中保存function replace_stuff(){return str_replace();}

  3. Add action with arbitrary arguments. 动作使用钩子传递的参数激发。但有时您并不关心这一点,只想在特定挂钩处使用自己的参数运行函数。从无数次中保存function echo_stuff(){echo \'stuff\'}; 还有更多。

    所以。。。

    是否有其他您想要和/或实际使用的用例?

    您将如何实现这样的包装器?有很多可能的方法(闭包、保留额外参数的全局变量、在回调中传递对象等)。

  4. PS 我有几个不同的实现(1)(3) 已经并且(如建议的)将在一段时间后发布我的代码,这样我就不会破坏乐趣了。:)

    Example

    当前方式:

    add_filter(\'wp_feed_cache_transient_lifetime\', \'change_transient_lifetime\', 10);
    
    function change_transient_lifetime($lifetime) {
    
        return 3600;
    }
    
    包装器:

    add_filter_return(\'wp_feed_cache_transient_lifetime\', 10, 3600);
    

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

我发布了我的代码Advanced Hooks API 图书馆

一些示例:

add_action_with_arguments(\'test\', \'printf\', 10, \'boo%s\', \'<br />\');
do_action(\'test\');
// boo

add_filter_return(\'test2\',10,\'boo\');
echo apply_filters(\'test2\',\'not boo\') . \'<br />\';
// boo

add_filter_append(\'test3\',10,\' and boo\');
echo apply_filters(\'test3\',\'boo\') . \'<br />\';
// boo and boo

add_filter_prepend(\'test4\',10,\'boo and \');
echo apply_filters(\'test4\',\'boo\') . \'<br />\';
// boo and boo

add_filter_replace(\'test5\',\'boo\',\'you thought...\');
echo apply_filters(\'test5\',\'boo\');
// you thought...

SO网友:wyrfel

对于像quick one liner returns这样的简单情况,应该记住可以在add filter调用中直接钩住匿名函数,例如:

add_filter(\'some_filter_hook\', function($v){return str_replace(\'..\', \'.\', $v);});

add_action(\'some_action_hook\', function(){echo \'....\';});

SO网友:hakre

你可能想调查一下magic class methods and overloading in PHP 将函数名作为参数传递。然后您可以根据函数名做出决策,如return__some_string 我提供了一些示例性的未经测试的代码:

class magiCall {
    public static function __callStatic ( string $name , array $arguments ) {
        // your code here, $name is the function name called.
    }
}

add_filter(\'hookname\', \'magiCall::return__the_string\');
我认为这个例子很好地说明了这个想法。

这是PHP 5.3。您可以使用__call 如果您有一个静态公共函数来返回回调,那么您可能可以将其编写得相当简单。请参阅上面的php手册链接。

SO网友:fuxia

对于简单的返回值,不需要很多额外的函数。这就是handycurrent_filter(). 您可以在自己的函数中使用它。

示例

<?php # -*- coding: utf-8 -*-
/*
Plugin Name: Filter System From Mail
Description: Sets the WP from mail address to the first admin’s mail and the from name to blog name.
Version:     1.1
Author:      Thomas Scholz
Author URI:  http://toscho.de
License:     GPL
*/

if ( ! function_exists( \'filter_system_from_mail\' ) )
{
    /**
     * First admin\'s e-mail address or blog name depending on current filter.
     *
     * @return string
     */
    function filter_system_from_mail()
    {
        return get_option( \'wp_mail_from\' == current_filter()
            ? \'admin_email\' : \'blogname\' );
    }

    add_filter( \'wp_mail_from\',      \'filter_system_from_mail\' );
    add_filter( \'wp_mail_from_name\', \'filter_system_from_mail\' );
}
还是…我误解了你的问题?

SO网友:kaiser

Ad anonymous or lambda functions) 在任何情况下,我都会避免这些,因为如果稍后检查挂钩,您将不知道其名称,也不会得到非常神秘的输出。调试将是一件痛苦的事。

Ad your A) 该方法看起来不错,并提供了一个非常简单的API(+1)。

Ad @hakre A) 我在我的框架核心中使用了几乎相同的函数[1]——通过“set\\u”扩展;异常-动态设置和获取变量。这样,我只需要用一个子类来扩展这个类,这个子类看起来像一个“仅变量”接口(那些应该可用的接口)。这是一种很好的有组织的方法,它只在为单个任务服务的文件中保留内容。通过这样的方式,您可以避免为每个TAK编写特定的函数,例如“\\u replace”等。

[1] 代码-我一直都在运行它,所以你可以称之为“已测试-并正常工作”

/**
 * Magic getter/setter method
 * Guesses for a class variable & calls/fills it or throws an exception.
 * Note: Already defined methods override this method.
 * 
 * Original @author Miles Keaton <[email protected]> 
 * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440}
 * The function was extended to also allow \'set\' tasks/calls and throws an exception.
 * 
 * @param (string) $name | Name of the property
 * @param unknown_type $args | arguments the function can take
 */
function __call( $name, $args )
{
    $_get = false;

    // See if we\'re calling a getter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == \'get_\' )
    {
        $_get = true;
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == \'get\' )
    {
        $_get = true;
        $varname = substr( $val, 3 );
    }

    // See if we\'re calling a setter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == \'set_\' )
    {
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == \'set\' )
    {
        $varname = substr( $val, 3 );
    }

    if ( ! isset( $varname ) )
        return new Exception( sprintf( __( "The method %1$s doesn\'t exist" ), "<em>{$val}</em>" ) );

    // Now see if that variable exists:
    foreach( $this as $class_var => $class_var_value )
    {
        if ( strtolower( $class_var ) == strtolower( $varname ) )
        {
            // GET
            if ( $_get )
            {
                return $this->{$class_var};
            }
            // SET
            else 
            {
                return $this->{$class_var} = $x[0];
            }
        }
    }

    return false;
}

结束

相关推荐

Custom Post Row Actions

我偶然发现this question 在写这个问题的时候。我有一个问题是关于这个问题的。我发现你用的是get_delete_post_link 筛选为我的操作创建一个新的url(或一个类似的函数——在任何情况下,我都会将该函数与布尔值一起使用)。唯一的问题是,I don\'t know how to capture the event now. 考虑到我在谷歌上找不到很多关于行后操作的例子,我将不胜感激-/public function _wp_filter_get_delete_post_link( $