Req #62113 [Opn->Sus]: ReflectionMethod::invoke && invokeArgs support static binding...
| From: | cmb@php.net | Date: | Tue, 14 Sep 2021 12:38:04 +0000 |
| Subject: | Req #62113 [Opn->Sus]: ReflectionMethod::invoke && invokeArgs support static binding... | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-236585@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=62113&edit=1
ID: 62113
Updated by: cmb@php.net
Reported by: nathanb@php.net
Summary: ReflectionMethod::invoke && invokeArgs support
static binding...
-Status: Open
+Status: Suspended
Type: Feature/Change Request
Package: Reflection related
Operating System: N/A
PHP Version: 5.4.3
Block user comment: N
Private report: N
New Comment:
Apparently, this went nowhere and skimming the internal
discussion[1] shows that this feature is controversial. As such
this feature requires the RFC process[2]. Anybody is welcome to
pursue it any time; I suspend this ticket until that happens.
[1] <https://externals.io/message/64943>
[2] <https://wiki.php.net/rfc/howto>
Previous Comments:
------------------------------------------------------------------------
[2013-01-31 18:36:21] lisachenko dot it at gmail dot com
Related discussion on mailing list: http://news.php.net/php.internals/64943
------------------------------------------------------------------------
[2012-09-12 14:47:31] nathanb@php.net
* Updated email address for profiling and spam reasons
------------------------------------------------------------------------
[2012-05-22 21:38:01] nathanb@php.net
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 this bug report at https://bugs.php.net/bug.php?id=62113&edit=1