获取WordPress中所有操作的调用者(插件/主题/核心)(&Hook)

时间:2018-08-10 作者:Akash Manhas

我正在开发一个插件,它将显示所有挂钩的调用者&;Wordpress中页面上的操作就像QueryMonitor一样。我知道global$wp_action&$wp\\u filter拥有所有信息,但它不提供操作或筛选器的调用方组件。

你能帮我解决这个问题吗。

如果需要代码,请记下注释。

提前谢谢。

代码:-

<?php
class MyTracker {

  static $hooks;

  static function track_hooks( ) {
    $filter = current_filter();
    if ( ! empty($GLOBALS[\'wp_filter\'][$filter]) ) {
      foreach ( $GLOBALS[\'wp_filter\'][$filter] as $priority => $tag_hooks ) {
        foreach ( $tag_hooks as $hook ) {
          if ( is_array($hook[\'function\']) )  {
            if ( is_object($hook[\'function\'][0]) ) {
              $func = get_class($hook[\'function\'][0]) . \'->\' . $hook[\'function\'][1];
            } elseif ( is_string($hook[\'function\'][0]) ) {
              $func = $hook[\'function\'][0] . \'::\' . $hook[\'function\'][1];
            }
          } elseif( $hook[\'function\'] instanceof Closure ) {
            $func = \'a closure\';
          } elseif( is_string($hook[\'function\']) ) {
            $func = $hook[\'function\'];
          }
          self::$hooks[] = \'On hook <b>"\' . $filter . \'"</b> run <b>\'. $func . \'</b> at priority \' . $priority;
        }
      }
    }
  }

}

add_action( \'all\', array(\'MyTracker\', \'track_hooks\') );

add_action( \'shutdown\', function() {
    echo implode( \'<br />\', MyTracker::$hooks );
}, 9999);
这将显示当前页面上的所有操作,我需要的是每个挂钩的执行时间。

2 个回复
最合适的回答,由SO网友:Nathan Johnson 整理而成

正如我在对问题的评论中所说,您可以使用PHP内部ReflectionFunction 类以获取可调用的文件名。下面的代码应该是帮助您的良好开端。它需要更多的逻辑来确定回调,而且其中大部分都应该从Monitor类中抽象出来。我也没有编写代码来获得主题、插件、核心或其他可能从文件名中添加挂钩的名称。如果您知道添加挂钩的文件,那么这应该相对容易做到。

<?php
/**
 * Plugin Name:  Monitor
 */

namespace WPSE\\Monitor;

class Monitor {
  protected $callbacks = [];

  protected function addCallback( $callback ) {
    $this->callbacks[] = $callback;
  }

  public function shutdown() {
    var_dump( $this->callbacks );
  }

  public function monitor() {
    global $wp_filter;
    $name = \\current_filter();
    if( ! isset( $wp_filter[ $name ] ) ) {
      return;
    }

    $action = $wp_filter[ $name ];

    foreach ( $action->callbacks as $priority => $callbacks ) {
      foreach( $callbacks as $callback ) {
        try {
          if( \\is_array( $callback[ \'function\' ] ) ) {
            if( \\is_object( $callback[ \'function\' ][ 0 ] ) ) {
              $class = \\get_class( $callback[ \'function\' ][ 0 ] );
              $callback[ \'name\' ] = $class . \'->\' . $callback[ \'function\' ][ 1 ] . \'()\';
              $ref = new \\ReflectionMethod( $class, $callback[ \'function\' ][ 1 ] );
            }
            elseif( \\is_string( $callback[ \'function\' ][ 0 ] ) ) {
              $callback[ \'name\' ] = $callback[ \'function\' ][ 0 ] . \'::\' . $callback[ \'function\' ][ 1 ];
              $ref = new \\ReflectionMethod( $callback[ \'function\' ][ 0 ], $callback[ \'function\' ][ 1 ] );
            }
          }
          elseif( $callback[ \'function\' ] instanceOf Closure ) {
            $callback[ \'name\' ] = \'closure\';
            $ref = new \\ReflectionMethod( $callback[ \'function\' ] );
          }
          elseif( \\is_string( $callback[ \'function\' ] ) ) {
            $callback[ \'name\' ] = $callback[ \'function\' ] . \'()\';
            $ref = new \\ReflectionMethod( $callback[ \'name\' ] );
          }
          else{
            return;
          }

          $callback[ \'filename\' ] = $ref->getFileName();

          $this->addCallback( $callback );

        } catch( \\ReflectionException $e ) {
          $callback[\'error\'] = new \\WP_Error( \'reflection_exception\', $e->getMessage() );
        }
      }
    }
  }
}
class MonitorInit {

  private static $monitor;

  public static function init() {
    self::$monitor = new Monitor();
    \\add_action( \'all\', [ self::$monitor, \'monitor\' ] );
    \\add_action( \'shutdown\', [ self::$monitor, \'shutdown\' ] );
  }
}
\\add_action( \'plugins_loaded\', __NAMESPACE__ . \'\\MonitorInit::init\', 0 );
Theplugins_loaded hook是第一个可用于常规插件的插件。因此,如果您想捕获在此之前添加的挂钩,您需要做一些棘手的事情。

SO网友:anmari

阿卡什,听起来你想列出所有插件&;添加了动作和过滤器的主题?

在这种情况下,请扫描所有插件;“add\\u action”和“add\\u filter”的wp内容中的主题文件,请注意文件路径(&U);添加它们的函数。将函数名与wp列表匹配,并排除任何实际上没有添加到wp中的,或者可能没有添加到wp中的-它们可能只在某些情况下添加,并且在插件运行时实际上不在wp变量中。列出完整的列表可能更安全?您可以注意到哪些插件和主题是非活动的,哪些插件和主题创建了自己的操作和过滤器等。

结束

相关推荐

Apply_Filters(‘the_content’,$Content)与DO_ShortCode($Content)

假设我有一个主题选项或自定义的postmeta文本区域。现在我想执行多个短代码、一般文本、图像等。最佳实践是什么?为什么?选项1:$content = //my text area data; echo apply_filters(\'the_content\', $content); 选项2:$content = //my text area data; echo do_shortcode($content); 请告诉我哪一个是最佳实践,以及为什么。EDIT让我详细描