hooks & filters and variables

时间:2011-03-19 作者:kaiser

我是updating the codex page example for action hooks, 在游戏中完成一些可重用的功能(最初是针对这里的一些Q@WA)。但后来我遇到了一个以前没有意识到的问题:在挂接到一个函数以修改变量的输出后,我再也无法决定是要回显输出还是只返回它。

The Problem: 我可以修改传递给do_action 用回调函数钩住。使用变量修改/添加的所有内容仅在回调函数中可用,但在do_action 在原始函数内部调用。

很高兴:我将其修改为一个工作示例,因此您可以将其复制/粘贴到functions.php 无需任何努力即可归档并查看/测试问题。

示例:

句柄数据函数

这是Handle\\u data\\u fn。文档记录有点过多,因为它应该作为如何解析默认值并将其与其他参数合并的指南
在do\\u action()调用之后,您可以在函数末尾看到问题。

/**
 * The "global" data handle function
 * 
 * This function can serve a lot of different purposes.
 * Incl. merging db values from an options entry with input arguments.
 * 
 * Throws a fully translateable Error if no database option name was specified.
 * Tells you from which file the Error was triggered and in which line you should search it.
 * Also tells you the "hook_data_handle_$args[\'UID\']" name of the action hook where the Error occured. 
 * 
 * Uses of external function calls in order of their appearance inside the function:
 * @uses:   isset()         - @link: http://php.net/manual/en/function.isset.php
 * @uses:   wp_die()        - @link: http://codex.wordpress.org/Function_Reference/wp_die
 * @uses:   printf()        - @link: http://php.net/manual/en/function.printf.php
 * @uses:   _e()            - @link: http://codex.wordpress.org/Function_Reference/_e (i18n function)
 * @uses:   apply_filters() - @link: http://codex.wordpress.org/Function_Reference/apply_filters
 * @uses:   wp_parse_args() - @link: http://codex.wordpress.org/Function_Reference/wp_parse_args
 * @uses:   extract()       - @link: http://php.net/manual/en/function.extract.php
 * @uses:   get_option()    - @link: http://codex.wordpress.org/Function_Reference/get_option
 * @uses:   do_action()     - @link: http://codex.wordpress.org/Function_Reference/do_action
 * @uses:   return          - @link: http://php.net/manual/en/function.return.php
 * 
 * @param:  (array) mixed $args | array of arguments - `$args[\'UID\']` is always a must have
 * @param:  $database           | true if you want to get and modify some db-option - `$args[\'name\']` then is a must have
 * @param:  $output             | result from the function - @internal: should not get set
 */
    function handle_data_fn( $args = array() )
    {
        // abort if we ain\'t got some unique identifier as argument
        if ( !isset( $args[\'UID\']) )
            return;

        // Trigger Error if an option should get retrieved from the database, 
        // but no option name was specified
        if ( !isset( $args[\'name\'] ) )
            wp_die( 
                printf(
                    _e(
                        \'You have to specify the "name" of a db-entry as argument inside a handle_data_fn at for the action hook: %1$s.\'."\\n".
                        \'Error triggered inside: file name %2$s (line number %3$s)\'
                     )
                    ,\'some_textdomain\'
                 )
                ,\'hook_data_handle_\'.$args[\'UID\'].\'`\'
                ,__FILE__
                ,__LINE__
            );


        // setup default arguments
        $defaults = ( 
            array(
                 \'UID\'      => null     // DB/css: #id | used to identify the data inside your database - $name[$ID] - can be used as css #id too
                ,\'name\'     => null     // name of DB field, should be a constant when fn get\'s triggered - just here for completeness, not needed
                ,\'args\'     => array(   // $arguments the function can handle - put default arguments in here as array data
                    // \'classes\'    => null     // css: .class - example
                 )
                ,\'output\'   => \'\'
                ,\'echo\'     => false    // if you want to echo the output or just save it in a var for later modifying
            ) 
        );
        // filter defaults
        $defaults = apply_filters( \'filter_defaults_\'.$args[\'UID\'], $defaults ); 

        // merge defaults with input arguments
        $args = wp_parse_args( $args, $defaults );
        extract( $args, EXTR_SKIP );

        // in case you want to call the global function again, 
        // but for some reason need to modify the merged result of defaults & arguments
        $args = apply_filters( \'filter_args_\'.$args[\'UID\'], $args );

        // retrieve the database option
        if ( isset( $args[\'name\'] ) )
            $options = get_option( $args[\'name\'] );


        # >>> start building $output

            // if true, echo the $output
            if ( isset( $args[\'echo\'] ) )
            {
                if ( $args[\'echo\'] === true )
                {
                    // do stuff here - your argument is the initial array
                    do_action( \'hook_data_handle_\'.$args[\'UID\'], $args, $options );

                    // Test output inside handle_fn: 
                    echo \'<pre>From inside handle_fn: \';
                        print_r($args);
                    echo \'</pre>\';

                    return;
                }

            }

            // else just return the $output
            // HOW CAN I NOT ECHO THE DATA HERE. 
            // STORING THE do_action return VALUE DOESN\'T WORK.
            // NEITHER DOES JUST returnING IT INSIDE THE CALLBACK FN \'modify_args_fn\' BELOW
            do_action( \'hook_data_handle_\'.$args[\'UID\'], $args, $options );
            return;

        # <<< end building $output
    }
回调函数用于a)构建初始数组和b)修改输出。

/**
 * EXAMPLE for how to add initial data to the handle_data_fn function.
 * 
 * @param (array) mixed $args
 */
    function build_args_fn ( $args ) {
        // build initial array
        $args = array(
             \'UID\'      => \'whatever_UID\'
            ,\'name\'     => \'some_options_name\'
            ,\'args\'     => array(
                \'class\' => \'example-wrap\'
             )
            ,\'echo\'     => true
        );

        handle_data_fn( $args );
    }
    // \'some_hook\' is some hook in a template file where the output should get echoed.
    add_action( \'some_hook\', \'build_args_fn\', 0, 1 );

/**
 * EXAMPLE for how to add content and modify the options from the DB inside a handle_data_fn function.
 * 
 * @param (array) mixed $args
 * @param (array) mixed $options    | db-options retrieved inside the oxo_parse function
 */
    function modify_args_fn ( $args, $options )
    {
        $args[\'output\'] .= \'<div class="container">\';
        $args[\'output\'] .= \'<div class="\'.$args[\'args\'][\'class\'].\'">\';
        $args[\'output\'] .= $options;
        $args[\'output\'] .= \'</div>\';
        $args[\'output\'] .= \'</div>\';

        // Test output inside callback fn
        echo \'<pre>From inside callback: \';
            print_r($args);
        echo \'</pre>\';

        // HERE\'S THE PROBLEM. I CAN\'T SIMPLE return IT, BECAUSE IT WOULDN\'T BE AVAILABLE INSIDE MY \'data_handle_fn\'.
        # return $args[\'output\'];
        // I HAVE TO PRINT IT TO GET SOME OUTPUT. THE $args[\'output\'] IS NOT AVAILABLE INSIDE THE \'handle_data_fn\' AFTER THE do_action CALL.
        return print $args[\'output\'];
    }
    // Name of the hook comes from \'UID\' argument in \'build_args_fn\' combined with \'hook_data_handle_\'
    add_action ( \'hook_data_handle_whatever_UID\', \'modify_args_fn\', 10, 2 );
感谢提供任何信息(&A);有关此问题的帮助。

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

如果要返回数据,最好的解决方案是使用apply\\u filters()并指示回调始终返回:

$output = apply_filters( \'hook_data_handle_\'.$args[\'UID\'], $args, $options );

if ( $args[\'echo\'] )
  echo $output;
else
  return $output;
一个不那么优雅的解决方案是output buffering.

结束

相关推荐