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_r
the_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' => '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”过滤器的所有注册函数的主要内容,如果未能解决你的问题,请参考以下文章