WordPress:如何获取“the_content”过滤器的所有注册函数

Posted

技术标签:

【中文标题】WordPress:如何获取“the_content”过滤器的所有注册函数【英文标题】:WordPress: How do I get all the registered functions for 'the_content' filter 【发布时间】:2011-07-10 14:24:34 【问题描述】:

我有一个关于 WordPress 的问题,特别是 3.0 版及更高版本。

有谁知道如何获取将应用或“注册”到 the_content 过滤器的所有函数的数组或列表?

这个想法是生成一个复选框列表,其中包含要从过滤器中删除的可能功能,例如 wpautop。我知道如何使用硬编码标签从过滤器中删除函数,但我希望创建一个更动态的解决方案。

如果有人对这是否可能以及如何完成有任何想法,我会非常感兴趣。谢谢。

【问题讨论】:

【参考方案1】:

从过滤器数组打印的简单函数?

function print_filters_for( $hook = '' ) 
    global $wp_filter;
    if( empty( $hook ) || !isset( $wp_filter[$hook] ) )
        return;

    print '<pre>';
    print_r( $wp_filter[$hook] );
    print '</pre>';

在你需要的地方调用它。

print_filters_for( 'the_content' );

【讨论】:

太棒了。感谢您的回复,我不知道 wp_filter 全局,但现在一切都说得通了。干杯:)【参考方案2】:

这是一个更高级的示例,除了来自$wp_filter 数组的数据之外,它还会显示附加挂钩的文件的路径,以及定义函数的代码行。

要获得与特定操作(或过滤器)挂钩的函数的基本列表,从过滤器数组中获取项目就足够了,但是由于可以以多种方式附加函数(作为类方法或闭包) list 将包含大量不相关的数据,其中包括以字符串形式呈现的对象。此示例将按优先级顺序仅显示相关数据:

函数名(取决于回调语法): 函数回调:'function_name' 对象方法:array( $object, 'function_name' ) 静态类方法:array( 'class_name', 'function_name' )'class_name::function_name' 关闭:function() 相对静态类方法:array( 'class_name', 'parent::function_name' ) 接受的参数 文件名 起跑线 身份证 优先级
function list_hooks( $hook = '' ) 
    global $wp_filter;

    if ( isset( $wp_filter[$hook]->callbacks ) )       
        array_walk( $wp_filter[$hook]->callbacks, function( $callbacks, $priority ) use ( &$hooks )            
            foreach ( $callbacks as $id => $callback )
                $hooks[] = array_merge( [ 'id' => $id, 'priority' => $priority ], $callback );
        );         
     else 
        return [];
    

    foreach( $hooks as &$item ) 
        // skip if callback does not exist
        if ( !is_callable( $item['function'] ) ) continue;

        // function name as string or static class method eg. 'Foo::Bar'
        if ( is_string( $item['function'] ) ) 
            $ref = strpos( $item['function'], '::' ) ? new ReflectionClass( strstr( $item['function'], '::', true ) ) : new ReflectionFunction( $item['function'] );
            $item['file'] = $ref->getFileName();
            $item['line'] = get_class( $ref ) == 'ReflectionFunction' 
                ? $ref->getStartLine() 
                : $ref->getMethod( substr( $item['function'], strpos( $item['function'], '::' ) + 2 ) )->getStartLine();

        // array( object, method ), array( string object, method ), array( string object, string 'parent::method' )
         elseif ( is_array( $item['function'] ) ) 

            $ref = new ReflectionClass( $item['function'][0] );

            // $item['function'][0] is a reference to existing object
            $item['function'] = array(
                is_object( $item['function'][0] ) ? get_class( $item['function'][0] ) : $item['function'][0],
                $item['function'][1]
            );
            $item['file'] = $ref->getFileName();
            $item['line'] = strpos( $item['function'][1], '::' )
                ? $ref->getParentClass()->getMethod( substr( $item['function'][1], strpos( $item['function'][1], '::' ) + 2 ) )->getStartLine()
                : $ref->getMethod( $item['function'][1] )->getStartLine();

        // closures
         elseif ( is_callable( $item['function'] ) )      
            $ref = new ReflectionFunction( $item['function'] );         
            $item['function'] = get_class( $item['function'] );
            $item['file'] = $ref->getFileName();
            $item['line'] = $ref->getStartLine();

               
    

    return $hooks;

由于可以在整个运行时添加和删除挂钩,因此输出取决于调用函数的时间(wp_footer 操作是获取完整列表的好地方)

print_rthe_content 过滤器的示例:

Array
(
    [0] => Array
        (
            [id] => 000000004c8a4a660000000011808a14run_shortcode
            [priority] => 8
            [function] => Array
                (
                    [0] => WP_Embed
                    [1] => run_shortcode
                )

            [accepted_args] => 1
            [file] => C:\xampp\htdocs\wordpress\wp-includes\class-wp-embed.php
            [line] => 58
        )

    [1] => Array
        (
            [id] => wptexturize
            [priority] => 10
            [function] => wptexturize
            [accepted_args] => 1
            [file] => C:\xampp\htdocs\wordpress\wp-includes\formatting.php
            [line] => 41
        )

    [2] => Array
        (
            [id] => 0000000006c5dc6d0000000064b1bc8e
            [priority] => 10
            [function] => Closure
            [accepted_args] => 1
            [file] => C:\xampp\htdocs\wordpress\wp-content\plugins\plugin\plugin.php
            [line] => 16
        )

    .....

编辑:2017-05-05

适用于WP_Hook 类 增加了优先级 已修复:如果回调不存在,则会引发错误,尽管 WordPress 也会为此引发警告 已修复:id相同但优先级不同的hook会覆盖前一个

【讨论】:

仅供参考-我尝试在我的插件中使用它,但它需要更多的错误捕获,因为如果有人添加了不存在的函数/方法,它会产生致命错误:Fatal error: Uncaught exception 'ReflectionException' with message 'Function Walker_Nav_Menu() does not exist' 我加了一点try/catch味here。 如果它也显示钩子优先级,那就特别棒了。 由于$wp_filter 是now a class,这将不再有效 截至 2018 年 6 月,这似乎有效。如果我们有大量插件的大型网站出现问题,我会报告。否则,此输出应该是current_filter() 上下文中的核心函数,例如get_action('wp_head', array('_wp_render_title_tag' =&gt; 'file')); 将返回...wp-includes\general-template.php。你带来了多么好的代码 sn-p @Danijel【参考方案3】:

基于print_filters_for的相同思想,为那些不仅需要打印还需要返回的人提供了一个扩展功能:

function filters_for( $hook = '', $return = FALSE ) 
    global $wp_filter;
    if( empty( $hook ) || !isset( $wp_filter[$hook] ) )
        return;

    if( $return ) 
        ob_start();
    

    print '<pre>';
    print_r( $wp_filter[$hook] );
    print '</pre>';

    if( $return ) 
        return ob_get_flush();
    

输出:

filters_for( 'the_content' );

获取和输出:

$output = filters_for( 'the_content', true );
echo $output;

【讨论】:

以上是关于WordPress:如何获取“the_content”过滤器的所有注册函数的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 WordPress 网站标志

WordPress 全屏图库 wordpress 插件 - 如何获取下一个和上一个按钮

如何获取 WordPress 各类页面的链接

如何获取 WordPress 各类页面的链接

Wordpress - 如何通过 AJAX 获取更多帖子?

Wordpress:如何通过 URL 获取日期?