wangsisi 发表于 2011-7-7 10:42:36

PHP中插件机制实现:mediawiki的钩子机制

mediawiki的扩展机制很多,钩子就是其中之一。不过,其钩子机制是通过函数来实现的。

简单地说,钩子机制通过三个方面来实现:

1、注册钩子;
2、放置钩子(事件:event handle);
3、运行钩子;

具体如下:
一、注册钩子

如:ArticleDelete


*Define function:   

function fnMyHook( &$article, &$user, &$reason, &$error ) { ... }

*Attach hook:   

$wgHooks['ArticleDelete'][] = 'fnMyHook';


二、钩子句柄
   


      wfRunHooks($event, $args = array()) 这里面就是wfRunHooks('ArticleDelete');放在在适当的位置



三、钩子的运行


/** * Because programmers assign to $wgHooks, we need to be very * careful about its contents. So, there's a lot more error-checking * in here than would normally be necessary. */function wfRunHooks($event, $args = array()) {    global $wgHooks;    // Return quickly in the most common case    if ( !isset( $wgHooks[$event] ) ) {      return true;    }    if (!is_array($wgHooks)) {      throw new MWException("Global hooks array is not an array!\n");      return false;    }    if (!is_array($wgHooks[$event])) {      throw new MWException("Hooks array for event '$event' is not an array!\n");      return false;    }    foreach ($wgHooks[$event] as $index => $hook) {      $object = null;      $method = null;      $func = null;      $data = null;      $have_data = false;      $closure = false;      /* $hook can be: a function, an object, an array of $function and $data,         * an array of just a function, an array of object and method, or an         * array of object, method, and data.         */      if ( is_array( $hook ) ) {            if ( count( $hook ) < 1 ) {                throw new MWException("Empty array in hooks for " . $event . "\n");            } else if ( is_object( $hook ) ) {                $object = $wgHooks[$event][$index];                if ( $object instanceof Closure ) {                  $closure = true;                  if ( count( $hook ) > 1 ) {                        $data = $hook;                        $have_data = true;                  }                } else {                  if ( count( $hook ) < 2 ) {                        $method = "on" . $event;                  } else {                        $method = $hook;                        if ( count( $hook ) > 2 ) {                            $data = $hook;                            $have_data = true;                        }                  }                }            } else if ( is_string( $hook ) ) {                $func = $hook;                if ( count( $hook ) > 1) {                  $data = $hook;                  $have_data = true;                }            } else {                throw new MWException( "Unknown datatype in hooks for " . $event . "\n" );            }      } else if ( is_string( $hook ) ) { # functions look like strings, too            $func = $hook;      } else if ( is_object( $hook ) ) {            $object = $wgHooks[$event][$index];            if ( $object instanceof Closure ) {                $closure = true;            } else {                $method = "on" . $event;            }      } else {            throw new MWException( "Unknown datatype in hooks for " . $event . "\n" );      }      /* We put the first data element on, if needed. */      if ( $have_data ) {            $hook_args = array_merge(array($data), $args);      } else {            $hook_args = $args;      }      if ( $closure ) {            $callback = $object;            $func = "hook-$event-closure";      } elseif ( isset( $object ) ) {            $func = get_class( $object ) . '::' . $method;            $callback = array( $object, $method );      } elseif ( false !== ( $pos = strpos( $func, '::' ) ) ) {            $callback = array( substr( $func, 0, $pos ), substr( $func, $pos + 2 ) );      } else {            $callback = $func;      }      // Run autoloader (workaround for call_user_func_array bug)      is_callable( $callback );      /* Call the hook. */      wfProfileIn( $func );      $retval = call_user_func_array( $callback, $hook_args );      wfProfileOut( $func );      /* String return is an error; false return means stop processing. */      if ( is_string( $retval ) ) {            global $wgOut;            $wgOut->showFatalError( $retval );            return false;      } elseif( $retval === null ) {            if ( $closure ) {                $prettyFunc = "$event closure";            } elseif( is_array( $callback ) ) {                if( is_object( $callback ) ) {                  $prettyClass = get_class( $callback );                } else {                  $prettyClass = strval( $callback );                }                $prettyFunc = $prettyClass . '::' . strval( $callback );            } else {                $prettyFunc = strval( $callback );            }            throw new MWException( "Detected bug in an extension! " .                "Hook $prettyFunc failed to return a value; " .                "should return true to continue hook processing or false to abort." );      } else if ( !$retval ) {            return false;      }    }    return true;}


就这三下!注意,其中重要的一个函数,

call_user_func_array();   //php函数
   主要是这个函数起作用。

页: [1]
查看完整版本: PHP中插件机制实现:mediawiki的钩子机制

BlueHost美国主机优惠码