From: Operating system: N/A PHP version: 5.4.3 Package: Reflection related Bug Type: Feature/Change Request Bug description:ReflectionMethod::invoke && invokeArgs support static binding...
Description: ------------ I think it'd be useful to be able to set the static binding of a class method if it's a static method. Currently you can only set the binding if it's not a static method, but my patch (see below) now will allow you to pass a string or an object to the ReflectionMethod::invoke and invokeArgs methods allowing you to set the static binding of static functions. The script below will work with the patch in place, but not work with current version of PHP because you *must* pass a valid object or null as the first argument, but if you are wanting it to call a static method my patch will allow you to set the Class the static method will run under. Test script: --------------- <?php trait A{ public static function static_method(){ return get_called_class(); } public function normal_method(){ return get_called_class(); } public function normal_method_this(){ return get_class($this); } } class B{ } class C extends B{ use A; public function test(){ $returns = array(); $returns[] = 'C => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invoke($this); $returns[] = 'B => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invoke('B'); $returns[] = 'C => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invoke('C'); $returns[] = 'A => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invoke(null); $returns[] = 'stdClass => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invoke(new stdClass); $returns[] = 'C => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invokeArgs($this, array()); $returns[] = 'B => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invokeArgs('B', array()); $returns[] = 'C => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invokeArgs('C', array()); $returns[] = 'A => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('static_method')->invokeArgs(null, array()); $returns[] = 'C => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invoke($this); $returns[] = 'stdClass => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invoke(new stdClass); $returns[] = 'B => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invoke(new B()); $returns[] = 'C => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invoke($this); $returns[] = 'stdClass => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invoke(new stdClass()); $returns[] = 'B => ' . current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invoke(new B()); // Normal methods need an object //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invokeArgs($this, array()); //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invoke('B', array()); // Error //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invoke('B', array()); // Error //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method')->invoke(null, array()); // Error //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invokeArgs($this, array()); //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invoke('B', array()); // Error //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invoke('B', array()); // Error //$returns[] = current((new ReflectionClass('C'))->getTraits())->getMethod('normal_method_this')->invoke(null, array()); // Error return $returns; } } $a = new C; print_r($a->test()); echo "\n"; Expected result: ---------------- Array ( [0] => C => C [1] => B => B [2] => C => C [3] => A => A [4] => stdClass => stdClass [5] => C => C [6] => B => B [7] => C => C [8] => A => A [9] => C => C [10] => stdClass => stdClass [11] => B => B [12] => C => C [13] => stdClass => stdClass [14] => B => B ) Actual result: -------------- Currently wont work because you can only pass objects or null as first parameter -- Edit bug report at https://bugs.php.net/bug.php?id=62113&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=62113&r=trysnapshot54 Try a snapshot (PHP 5.3): https://bugs.php.net/fix.php?id=62113&r=trysnapshot53 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=62113&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=62113&r=fixed Fixed in SVN and need be documented: https://bugs.php.net/fix.php?id=62113&r=needdocs Fixed in release: https://bugs.php.net/fix.php?id=62113&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=62113&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=62113&r=needscript Try newer version: https://bugs.php.net/fix.php?id=62113&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=62113&r=support Expected behavior: https://bugs.php.net/fix.php?id=62113&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=62113&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=62113&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=62113&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=62113&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=62113&r=dst IIS Stability: https://bugs.php.net/fix.php?id=62113&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=62113&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=62113&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=62113&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=62113&r=mysqlcfg