我怎样才能使这个PHP类静态

时间:2017-07-11 11:01:18

标签: php class

我使用这个类在我的用户管理系统中使用像wordpress一样的钩子和过滤器,我使用自动加载类来加载我的所有类,但它不会识别这个类,除非它是静态的,如何我可以让这个类静态吗?

<?php 
class Hooks
{
/**
 * $filters holds list of hooks
 * @access public
 * @since 0.1
 * @var array
 */
protected static $filters = [];
/**
 * $merged_filters
 * @var array
 */
protected static $merged_filters = [];
/**
 * $actions 
 * @var array
 */
protected static $actions = [];
/**
 * $current_filter  holds the name of the current filter
 * @access public
 * @since 0.1
 * @var array
 */
protected static $current_filter = [];

// Disable object instantiation
private function __construct() {}

/**
 * gets instance of this class
 * @access public
 * @since 0.1

public static function getInstance()
{
    if (self::$_instance === null) {
        self::$_instance = new Hooks();
    }
    return self::$_instance;
}
*/
/**
 * FILTERS
 */

/**
 * add_filter Hooks a function or method to a specific filter action.
 * @access public
 * @since 0.1
 * @param string $tag The name of the filter to hook the $function_to_add to.
 * @param callback $function_to_add The name of the function to be called when the filter is applied.
 * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
 * @param int $accepted_args optional. The number of arguments the function accept (default 1).
 * @return boolean true
 */
public static function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
  $idx =  self::_filter_build_unique_id($tag, $function_to_add, $priority);
  self::$filters[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
  unset( self::$merged_filters[ $tag ] );
  return true;
}
/**
 * remove_filter Removes a function from a specified filter hook.
 * @access public
 * @since 0.1
 * @param string $tag The filter hook to which the function to be removed is hooked.
 * @param callback $function_to_remove The name of the function which should be removed.
 * @param int $priority optional. The priority of the function (default: 10).
 * @param int $accepted_args optional. The number of arguments the function accepts (default: 1).
 * @return boolean Whether the function existed before it was removed.
 */
public static function remove_filter( $tag, $function_to_remove, $priority = 10 ) {
  $function_to_remove = self::_filter_build_unique_id($tag, $function_to_remove, $priority);

  $r = isset(self::filters[$tag][$priority][$function_to_remove]);

  if ( true === $r) {
    unset(self::$filters[$tag][$priority][$function_to_remove]);
    if ( empty(self::$filters[$tag][$priority]) )
      unset(self::$filters[$tag][$priority]);
    unset(self::$merged_filters[$tag]);
  }
  return $r;
}
/**
 * remove_all_filters Remove all of the hooks from a filter.
 * @access public
 * @since 0.1
 * @param string $tag The filter to remove hooks from.
 * @param int $priority The priority number to remove.
 * @return bool True when finished.
 */
public static function remove_all_filters($tag, $priority = false) {
  if( isset(self::$filters[$tag]) ) {
    if( false !== $priority && isset(self::$filters[$tag][$priority]) )
      unset(self::$filters[$tag][$priority]);
    else
      unset(self::$filters[$tag]);
  }

  if( isset(self::$merged_filters[$tag]) )
    unset(self::$merged_filters[$tag]);

  return true;
}
/**
 * has_filter  Check if any filter has been registered for a hook.
 * @access public
 * @since 0.1
 * @param string $tag The name of the filter hook.
 * @param callback $function_to_check optional.
 * @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered.
 *   When checking a specific function, the priority of that hook is returned, or false if the function is not attached.
 *   When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false
 *   (e.g.) 0, so use the === operator for testing the return value.
 */
public static function has_filter($tag, $function_to_check = false) {
  $has = !empty(self::$filters[$tag]);
  if ( false === $function_to_check || false == $has )
    return $has;

  if ( !$idx = self::_filter_build_unique_id($tag, $function_to_check, false) )
    return false;

  foreach ( (array) array_keys(self::$filters[$tag]) as $priority ) {
    if ( isset(self::$filters[$tag][$priority][$idx]) )
      return $priority;
  }
  return false;
}
/**
 * apply_filters Call the functions added to a filter hook.
 * @access public
 * @since 0.1
 * @param string $tag The name of the filter hook.
 * @param mixed $value The value on which the filters hooked to <tt>$tag</tt> are applied on.
 * @param mixed $var,... Additional variables passed to the functions hooked to <tt>$tag</tt>.
 * @return mixed The filtered value after all hooked functions are applied to it.
 */
public static function apply_filters($tag, $value) {
  $args = array();
  // Do 'all' actions first
  if ( isset(self::$filters['all']) ) {
    self::$current_filter[] = $tag;
    $args = func_get_args();
    self::_call_all_hook($args);
  }

  if ( !isset(self::$filters[$tag]) ) {
    if ( isset(self::$filters['all']) )
      array_pop(self::$current_filter);
    return $value;
  }

  if ( !isset(self::$filters['all']) )
    self::$current_filter[] = $tag;

  // Sort
  if ( !isset( self::$merged_filters[ $tag ] ) ) {
    ksort(self::$filters[$tag]);
    self::$merged_filters[ $tag ] = true;
  }

  reset( self::$filters[ $tag ] );

  if ( empty($args) )
    $args = func_get_args();

  do {
    foreach( (array) current(self::$filters[$tag]) as $the_ )
      if ( !is_null($the_['function']) ){
        $args[1] = $value;
        $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
      }

  } while ( next(self::$filters[$tag]) !== false );

  array_pop( self::$current_filter );

  return $value;
}
/**
 * apply_filters_ref_array Execute functions hooked on a specific filter hook, specifying arguments in an array.
 * @access public
 * @since 0.1
 * @param string $tag The name of the filter hook.
 * @param array $args The arguments supplied to the functions hooked to <tt>$tag</tt>
 * @return mixed The filtered value after all hooked functions are applied to it.
 */
public static function apply_filters_ref_array($tag, $args) {
  // Do 'all' actions first
  if ( isset(self::$filters['all']) ) {
    self::$current_filter[] = $tag;
    $all_args = func_get_args();
    self::_call_all_hook($all_args);
  }

  if ( !isset(self::$filters[$tag]) ) {
    if ( isset(self::$filters['all']) )
      array_pop(self::$current_filter);
    return $args[0];
  }

  if ( !isset(self::$filters['all']) )
    self::$current_filter[] = $tag;

  // Sort
  if ( !isset( self::$merged_filters[ $tag ] ) ) {
    ksort(self::$filters[$tag]);
    self::$merged_filters[ $tag ] = true;
  }

  reset( self::$filters[ $tag ] );

  do {
    foreach( (array) current(self::$filters[$tag]) as $the_ )
      if ( !is_null($the_['function']) )
        $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

  } while ( next(self::$filters[$tag]) !== false );

  array_pop( self::$current_filter );

  return $args[0];
}

/**
 * ACTIONS
 */

/**
 * add_action Hooks a function on to a specific action.
 * @access public
 * @since 0.1
 * @param string $tag The name of the action to which the $function_to_add is hooked.
 * @param callback $function_to_add The name of the function you wish to be called.
 * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
 * @param int $accepted_args optional. The number of arguments the function accept (default 1).
 */
public static function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
  return self::add_filter($tag, $function_to_add, $priority, $accepted_args);
}
/**
 * has_action Check if any action has been registered for a hook.
 * @access public
 * @since 0.1
 * @param string $tag The name of the action hook.
 * @param callback $function_to_check optional.
 * @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered.
 *   When checking a specific function, the priority of that hook is returned, or false if the function is not attached.
 *   When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false
 *   (e.g.) 0, so use the === operator for testing the return value.
 */
public static function has_action($tag, $function_to_check = false) {
  return self::has_filter($tag, $function_to_check);
}
/**
 * remove_action Removes a function from a specified action hook.
 * @access public
 * @since 0.1
 * @param string $tag The action hook to which the function to be removed is hooked.
 * @param callback $function_to_remove The name of the function which should be removed.
 * @param int $priority optional The priority of the function (default: 10).
 * @return boolean Whether the function is removed.
 */
public static function remove_action( $tag, $function_to_remove, $priority = 10 ) {
  return self::remove_filter( $tag, $function_to_remove, $priority );
}
/**
 * remove_all_actions Remove all of the hooks from an action.
 * @access public
 * @since 0.1
 * @param string $tag The action to remove hooks from.
 * @param int $priority The priority number to remove them from.
 * @return bool True when finished.
 */
public static function remove_all_actions($tag, $priority = false) {
  return self::remove_all_filters($tag, $priority);
}
/**
 * do_action Execute functions hooked on a specific action hook.
 * @access public
 * @since 0.1
 * @param string $tag The name of the action to be executed.
 * @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action.
 * @return null Will return null if $tag does not exist in $filter array
 */
public static function do_action($tag, $arg = '') {

  if ( ! isset(self::$actions) )
    self::$actions = array();

  if ( ! isset(self::$actions[$tag]) )
    self::$actions[$tag] = 1;
  else
    ++self::$actions[$tag];

  // Do 'all' actions first
  if ( isset(self::$filters['all']) ) {
    self::$current_filter[] = $tag;
    $all_args = func_get_args();
    self::_call_all_hook($all_args);
  }

  if ( !isset(self::$filters[$tag]) ) {
    if ( isset(self::$filters['all']) )
      array_pop(self::$current_filter);
    return;
  }

  if ( !isset(self::$filters['all']) )
    self::$current_filter[] = $tag;

  $args = array();
  if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
    $args[] =& $arg[0];
  else
    $args[] = $arg;
  for ( $a = 2; $a < func_num_args(); $a++ )
    $args[] = func_get_arg($a);

  // Sort
  if ( !isset( self::$merged_filters[ $tag ] ) ) {
    ksort(self::$filters[$tag]);
    self::$merged_filters[ $tag ] = true;
  }

  reset( self::$filters[ $tag ] );

  do {
    foreach ( (array) current(self::$filters[$tag]) as $the_ )
      if ( !is_null($the_['function']) )
        call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

  } while ( next(self::$filters[$tag]) !== false );

  array_pop(self::$current_filter);
}
/**
 * do_action_ref_array Execute functions hooked on a specific action hook, specifying arguments in an array.
 * @access public
 * @since 0.1
 * @param string $tag The name of the action to be executed.
 * @param array $args The arguments supplied to the functions hooked to <tt>$tag</tt>
 * @return null Will return null if $tag does not exist in $filter array
 */
public static function do_action_ref_array($tag, $args) {

  if ( ! isset(self::$actions) )
    self::$actions = [];

  if ( ! isset(self::$actions[$tag]) )
    self::$actions[$tag] = 1;
  else
    ++self::$actions[$tag];

  // Do 'all' actions first
  if ( isset(self::$filters['all']) ) {
    self::$current_filter[] = $tag;
    $all_args = func_get_args();
    self::_call_all_hook($all_args);
  }

  if ( !isset(self::$filters[$tag]) ) {
    if ( isset(self::$filters['all']) )
      array_pop(self::$current_filter);
    return;
  }

  if ( !isset(self::$filters['all']) )
    self::$current_filter[] = $tag;

  // Sort
  if ( !isset( $merged_filters[ $tag ] ) ) {
    ksort(self::$filters[$tag]);
    $merged_filters[ $tag ] = true;
  }

  reset( self::$filters[ $tag ] );

  do {
    foreach( (array) current(self::$filters[$tag]) as $the_ )
      if ( !is_null($the_['function']) )
        call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

  } while ( next(self::$filters[$tag]) !== false );

  array_pop(self::$current_filter);
}
/**
 * did_action Retrieve the number of times an action is fired.
 * @access public
 * @since 0.1
 * @param string $tag The name of the action hook.
  * @return int The number of times action hook <tt>$tag</tt> is fired
 */
public static function did_action($tag) {

  if ( ! isset( self::$actions ) || ! isset( self::$actions[$tag] ) )
    return 0;

  return self::$actions[$tag];
}

/**
 * HELPERS
 */

/**
 * current_filter Retrieve the name of the current filter or action.
 * @access public
 * @since 0.1
 * @return string Hook name of the current filter or action.
 */
public static function current_filter() {
  return end( self::$current_filter );
}
/**
 * Retrieve the name of the current action.
 *
 * @since 0.1.2
 *
 * @uses current_filter()
 *
 * @return string Hook name of the current action.
 */
public static function current_action() {
  return self::current_filter();
}

/**
 * Retrieve the name of a filter currently being processed.
 *
 * The function current_filter() only returns the most recent filter or action
 * being executed. did_action() returns true once the action is initially
 * processed. This function allows detection for any filter currently being
 * executed (despite not being the most recent filter to fire, in the case of
 * hooks called from hook callbacks) to be verified.
 *
 * @since 0.1.2
 *
 * @see current_filter()
 * @see did_action()
 * @global array $wp_current_filter Current filter.
 *
 * @param null|string $filter Optional. Filter to check. Defaults to null, which
 *                            checks if any filter is currently being run.
 * @return bool Whether the filter is currently in the stack
 */
public static function doing_filter( $filter = null ) {
  if ( null === $filter ) {
    return ! empty( self::$current_filter );
  } 
  return in_array( $filter, self::$current_filter );
}

/**
 * Retrieve the name of an action currently being processed.
 *
 * @since 0.1.2
 *
 * @uses doing_filter()
 *
 * @param string|null $action Optional. Action to check. Defaults to null, which checks
 *                            if any action is currently being run.
 * @return bool Whether the action is currently in the stack.
 */
public static function doing_action( $action = null ) {
  return self::doing_filter( $action );
}

/**
 * _filter_build_unique_id Build Unique ID for storage and retrieval.
 * @param string $tag Used in counting how many hooks were applied
 * @param callback $function Used for creating unique id
 * @param int|bool $priority Used in counting how many hooks were applied. If === false and $function is an object reference, we return the unique id only if it already has one, false otherwise.
 * @return string|bool Unique ID for usage as array key or false if $priority === false and $function is an object reference, and it does not already have a unique id.
 */
private static function _filter_build_unique_id($tag, $function, $priority) {
  static $filter_id_count = 0;

  if ( is_string($function) )
    return $function;

  if ( is_object($function) ) {
    // Closures are currently implemented as objects
    $function = array( $function, '' );
  } else {
    $function = (array) $function;
  }

  if (is_object($function[0]) ) {
    // Object Class Calling
    if ( function_exists('spl_object_hash') ) {
      return spl_object_hash($function[0]) . $function[1];
    } else {
      $obj_idx = get_class($function[0]).$function[1];
      if ( !isset($function[0]->filter_id) ) {
        if ( false === $priority )
          return false;
        $obj_idx .= isset(self::$filters[$tag][$priority]) ? count((array)self::$filters[$tag][$priority]) : $filter_id_count;
        $function[0]->filter_id = $filter_id_count;
        ++$filter_id_count;
      } else {
        $obj_idx .= $function[0]->filter_id;
      }

      return $obj_idx;
    }
  } else if ( is_string($function[0]) ) {
    // Static Calling
    return $function[0].$function[1];
  }
}

/**
 * __call_all_hook
 * @access public
 * @since 0.1
 * @param  (array) $args [description]
 */
public static function __call_all_hook($args) {
  reset( self::$filters['all'] );
  do {
    foreach( (array) current(self::$filters['all']) as $the_ )
      if ( !is_null($the_['function']) )
        call_user_func_array($the_['function'], $args);

  } while ( next(self::$filters['all']) !== false );
}
}//end class

/** 
* Hooks Shortcuts not in class 
*/ 

function add_action($hook, $function) {
   return Hooks::add_action($hook, $function); 
}

function has_action($hook, $function) {
   return Hooks::has_action($hook, $function); 
} 

function do_action($hook, $args = '') { 
   return Hooks::do_action($hook, $args); 
} 

function remove_action($hook, $function, $priority = '') {
   return Hooks::remove_action($hook, $function, $priority);
}

function remove_all_actions($hook, $priority = '') { 
   return Hooks::remove_all_actions($hook, $priority); 
}
?>

编辑:继承我的自动加载器类:

 <?php
  class Autoloader {
/**
 * File extension as a string. Defaults to ".php".
 */
protected static $fileExt = '.php';

/**
 * The top level directory where recursion will begin. Defaults to the current
 * directory.
 */
protected static $pathTop = __DIR__;

/**
 * A placeholder to hold the file iterator so that directory traversal is only
 * performed once.
 */
protected static $fileIterator = null;

/**
 * Autoload function for registration with spl_autoload_register
 *
 * Looks recursively through project directory and loads class files based on
 * filename match.
 *
 * @param string $className
 */
public static function loader($className) {

    $directory = new RecursiveDirectoryIterator(static::$pathTop, RecursiveDirectoryIterator::SKIP_DOTS);

    if (is_null(static::$fileIterator)) {

        static::$fileIterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::LEAVES_ONLY);

    }

    $filename = $className . static::$fileExt;

    foreach (static::$fileIterator as $file) {

        if (strtolower($file->getFilename()) === strtolower($filename)) {

            if ($file->isReadable()) {

                include_once $file->getPathname();

            }
            break;

        }

    }

}

/**
 * Sets the $fileExt property
 *
 * @param string $fileExt The file extension used for class files.  Default is "php".
 */
public static function setFileExt($fileExt) {
    static::$fileExt = $fileExt;
}

/**
 * Sets the $path property
 *
 * @param string $path The path representing the top level where recursion should
 *                     begin. Defaults to the current directory.
 */
public static function setPath($path) {
    static::$pathTop = $path;
}

}

Autoloader::setFileExt('.php');
spl_autoload_register('Autoloader::loader');
?>

2 个答案:

答案 0 :(得分:3)

您不能将类声明为静态,但您可以执行以下操作:

  • 限制对象实例化:

    private function __construct() {} // Constructor disabled
    private function __clone()     {} // Cloning disabled
    private function __wakeup()    {} // Serialization disabled
    
  • 声明所有属性静态

  • 声明所有方法静态

你有一个类似静态的类。 例如:

<?php 
class Hooks
{
  protected static $filters = [];
  protected static $merged_filters = [];
  protected static $actions = [];
  protected static $current_filter = [];
  // You don't need an instance unless you want to implement a simpleton pattern.
  // protected static $_instance;

  // Disable object instantiation
  private function __construct() {}
  private function __clone()     {}
  private function __serialize() {}

  // You don't need this either:
  // public static function getInstance() { ... }

  public static function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1)
  {
    $idx = self::filter_build_unique_id($tag, $function_to_add, $priority);
    self::$filters[$tag][$priority][$idx] = ['function' => $function_to_add, 'accepted_args' => $accepted_args];
    unset( self::$merged_filters[ $tag ] );
    return true;
  }

  //
  // ...and so on...
  //

答案 1 :(得分:1)

回答我的自动加载器没有加载我的类的问题,我将需求移到我的自动加载器之前到session_start();在我的系统和bam!很好地自动加载:)