<?php
// Reduced core class from MediaWiki to demonstrate an issue starting with 7.1.0alpha2
// https://github.com/wikimedia/mediawiki/blob/master/includes/Hooks.php
class Hooks {
protected static $handlers = array();
public static function register( $name, $callback ) {
if ( !isset( self::$handlers[$name] ) ) {
self::$handlers[$name] = array();
}
self::$handlers[$name][] = $callback;
}
public static function run( $event, array $args = array() ) {
foreach ( self::$handlers[$event] as $hook ) {
if ( !is_array( $hook ) ) {
$hook = array( $hook );
}
if ( !array_filter( $hook ) ) {
continue;
} elseif ( is_array( $hook[0] ) ) {
$hook = array_merge( $hook[0], array_slice( $hook, 1 ) );
}
if ( $hook[0] instanceof Closure ) {
$func = "hook-$event-closure";
$callback = array_shift( $hook );
} elseif ( is_object( $hook[0] ) ) {
$object = array_shift( $hook );
$method = array_shift( $hook );
if ( $method === null ) {
$method = "on$event";
}
$func = get_class( $object ) . '::' . $method;
$callback = array( $object, $method );
} elseif ( is_string( $hook[0] ) ) {
$func = $callback = array_shift( $hook );
}
$retval = null;
$badhookmsg = null;
$hook_args = array_merge( $hook, $args );
$retval = call_user_func_array( $callback, $args );
}
}
}
Hooks::register( 'foo', function( &$foo, &$var ) {
$var = $var . '-bar';
} );
//Stub class using &$this as direct reference
class Foo {
public function doSomething( $var ) {
Hooks::run( 'foo', array( &$this, &$var ) );
return $var;
}
}
// Stub class causes no error after $this is being redeclared
class Foo2 {
public function doSomething( $var ) {
$foo = $this;
Hooks::run( 'foo', array( &$foo, &$var ) );
return $var;
}
}
// Causes an error
$fooA = new Foo();
$varA = $fooA->doSomething( '123' );
echo "Foo: \n";
echo $varA . "\n";
// Causes no error
$fooB = new Foo2();
$varB = $fooB->doSomething( '123' );
echo "Foo2: \n";
echo $varB;
preferences:
72.1 ms | 402 KiB | 5 Q