Skip to content

Commit f41220f

Browse files
committedJul 18, 2023
Implement ReflectionMethod::createFromMethodName()
1 parent 840d665 commit f41220f

13 files changed

+92
-22
lines changed
 

‎ext/reflection/php_reflection.c

+28-8
Original file line numberDiff line numberDiff line change
@@ -3185,9 +3185,9 @@ ZEND_METHOD(ReflectionIntersectionType, getTypes)
31853185
/* }}} */
31863186

31873187
/* {{{ Constructor. Throws an Exception in case the given method does not exist */
3188-
ZEND_METHOD(ReflectionMethod, __construct)
3188+
static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
31893189
{
3190-
zend_object *arg1_obj;
3190+
zend_object *arg1_obj = NULL;
31913191
zend_string *arg1_str;
31923192
zend_string *arg2_str = NULL;
31933193

@@ -3202,11 +3202,17 @@ ZEND_METHOD(ReflectionMethod, __construct)
32023202
reflection_object *intern;
32033203
zend_function *mptr;
32043204

3205-
ZEND_PARSE_PARAMETERS_START(1, 2)
3206-
Z_PARAM_OBJ_OR_STR(arg1_obj, arg1_str)
3207-
Z_PARAM_OPTIONAL
3208-
Z_PARAM_STR_OR_NULL(arg2_str)
3209-
ZEND_PARSE_PARAMETERS_END();
3205+
if (is_constructor) {
3206+
ZEND_PARSE_PARAMETERS_START(1, 2)
3207+
Z_PARAM_OBJ_OR_STR(arg1_obj, arg1_str)
3208+
Z_PARAM_OPTIONAL
3209+
Z_PARAM_STR_OR_NULL(arg2_str)
3210+
ZEND_PARSE_PARAMETERS_END();
3211+
} else {
3212+
ZEND_PARSE_PARAMETERS_START(1, 1)
3213+
Z_PARAM_STR(arg1_str)
3214+
ZEND_PARSE_PARAMETERS_END();
3215+
}
32103216

32113217
if (arg1_obj) {
32123218
if (!arg2_str) {
@@ -3250,7 +3256,12 @@ ZEND_METHOD(ReflectionMethod, __construct)
32503256
zend_string_release(class_name);
32513257
}
32523258

3253-
object = ZEND_THIS;
3259+
if (is_constructor) {
3260+
object = ZEND_THIS;
3261+
} else {
3262+
object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : reflection_method_ptr);
3263+
object = return_value;
3264+
}
32543265
intern = Z_REFLECTION_P(object);
32553266

32563267
lcname = zend_str_tolower_dup(method_name, method_name_len);
@@ -3276,8 +3287,17 @@ ZEND_METHOD(ReflectionMethod, __construct)
32763287
intern->ref_type = REF_TYPE_FUNCTION;
32773288
intern->ce = ce;
32783289
}
3290+
3291+
/* {{{ Constructor. Throws an Exception in case the given method does not exist */
3292+
ZEND_METHOD(ReflectionMethod, __construct) {
3293+
instantiate_reflection_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
3294+
}
32793295
/* }}} */
32803296

3297+
ZEND_METHOD(ReflectionMethod, createFromMethodName) {
3298+
instantiate_reflection_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
3299+
}
3300+
32813301
/* {{{ Returns a string representation */
32823302
ZEND_METHOD(ReflectionMethod, __toString)
32833303
{

‎ext/reflection/php_reflection.stub.php

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ class ReflectionMethod extends ReflectionFunctionAbstract
205205

206206
public function __construct(object|string $objectOrMethod, ?string $method = null) {}
207207

208+
public static function createFromMethodName(string $method): static {}
209+
208210
public function __toString(): string {}
209211

210212
/** @tentative-return-type */

‎ext/reflection/php_reflection_arginfo.h

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎ext/reflection/tests/008.phpt

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ foreach ($a as $val) {
1111
} catch (Exception $e) {
1212
var_dump($e->getMessage());
1313
}
14+
15+
try {
16+
ReflectionMethod::createFromMethodName($val);
17+
} catch (Exception $e) {
18+
var_dump($e->getMessage());
19+
}
1420
}
1521

1622
$a = array("", 1, "");
@@ -28,10 +34,16 @@ echo "Done\n";
2834
?>
2935
--EXPECT--
3036
string(90) "ReflectionMethod::__construct(): Argument #1 ($objectOrMethod) must be a valid method name"
37+
string(91) "ReflectionMethod::createFromMethodName(): Argument #1 ($method) must be a valid method name"
3138
string(90) "ReflectionMethod::__construct(): Argument #1 ($objectOrMethod) must be a valid method name"
39+
string(91) "ReflectionMethod::createFromMethodName(): Argument #1 ($method) must be a valid method name"
3240
string(23) "Class "" does not exist"
41+
string(23) "Class "" does not exist"
42+
string(24) "Class "a" does not exist"
3343
string(24) "Class "a" does not exist"
3444
string(23) "Class "" does not exist"
45+
string(23) "Class "" does not exist"
46+
string(24) "Class "a" does not exist"
3547
string(24) "Class "a" does not exist"
3648
string(23) "Class "" does not exist"
3749
string(24) "Class "1" does not exist"

‎ext/reflection/tests/010.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Bar extends Foo {
1010
function func() {
1111
}
1212
}
13-
$m = new ReflectionMethod("Bar::func");
13+
$m = ReflectionMethod::createFromMethodName("Bar::func");
1414
echo $m;
1515
?>
1616
--EXPECTF--

‎ext/reflection/tests/ReflectionMethod_constructor_basic.phpt

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var_dump($methodInfo->isConstructor());
1616
class ExtendsNewCtor extends NewCtor {
1717
}
1818
echo "\nInherited new-style constructor\n";
19-
$methodInfo = new ReflectionMethod("ExtendsNewCtor::__construct");
19+
$methodInfo = ReflectionMethod::createFromMethodName("ExtendsNewCtor::__construct");
2020
var_dump($methodInfo->isConstructor());
2121

2222
class X {
@@ -25,13 +25,13 @@ class X {
2525
}
2626
}
2727
echo "\nNot a constructor:\n";
28-
$methodInfo = new ReflectionMethod("X::Y");
28+
$methodInfo = ReflectionMethod::createFromMethodName("X::Y");
2929
var_dump($methodInfo->isConstructor());
3030

3131
class Y extends X {
3232
}
3333
echo "\nInherited method of the same name as the class:\n";
34-
$methodInfo = new ReflectionMethod("Y::Y");
34+
$methodInfo = ReflectionMethod::createFromMethodName("Y::Y");
3535
var_dump($methodInfo->isConstructor());
3636

3737
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
ReflectionMethod::createFromMethodName()
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function bar() {}
8+
}
9+
10+
class MyReflectionMethod extends ReflectionMethod {}
11+
12+
$m = MyReflectionMethod::createFromMethodName("Foo::bar");
13+
14+
var_dump($m);
15+
16+
try {
17+
$m = MyReflectionMethod::createFromMethodName("Foo::baz");
18+
} catch (Exception $e) {
19+
echo $e->getMessage() . "\n";
20+
}
21+
22+
?>
23+
--EXPECTF--
24+
object(MyReflectionMethod)#%d (%d) {
25+
["name"]=>
26+
string(3) "bar"
27+
["class"]=>
28+
string(3) "Foo"
29+
}
30+
Method Foo::baz() does not exist

‎ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ $testClassInstance->prop = "Hello";
2727

2828
$foo = new ReflectionMethod($testClassInstance, 'foo');
2929
$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs');
30-
$methodThatThrows = new ReflectionMethod("TestClass::willThrow");
30+
$methodThatThrows = ReflectionMethod::createFromMethodName("TestClass::willThrow");
3131

3232

3333
echo "Public method:\n";

‎ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ $testClassInstance = new TestClass();
3434
$testClassInstance->prop = "Hello";
3535

3636
$foo = new ReflectionMethod($testClassInstance, 'foo');
37-
$staticMethod = new ReflectionMethod('TestClass::staticMethod');
37+
$staticMethod = ReflectionMethod::createFromMethodName('TestClass::staticMethod');
3838
$privateMethod = new ReflectionMethod("TestClass::privateMethod");
3939

4040
echo "\nNon-instance:\n";

‎ext/reflection/tests/ReflectionMethod_invoke_error1.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ abstract class AbstractClass {
2222
}
2323

2424
$foo = new ReflectionMethod('TestClass', 'foo');
25-
$privateMethod = new ReflectionMethod("TestClass::privateMethod");
25+
$privateMethod = ReflectionMethod::createFromMethodName("TestClass::privateMethod");
2626

2727
$testClassInstance = new TestClass();
2828
$testClassInstance->prop = "Hello";
@@ -45,7 +45,7 @@ echo "\nPrivate method:\n";
4545
var_dump($privateMethod->invoke($testClassInstance));
4646

4747
echo "\nAbstract method:\n";
48-
$abstractMethod = new ReflectionMethod("AbstractClass::foo");
48+
$abstractMethod = ReflectionMethod::createFromMethodName("AbstractClass::foo");
4949
try {
5050
$abstractMethod->invoke(true);
5151
} catch (ReflectionException $e) {

‎ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ class TestClass {
1111
}
1212
}
1313

14-
$methodInfo = new ReflectionMethod('TestClass::foo');
14+
$methodInfo = ReflectionMethod::createFromMethodName('TestClass::foo');
1515
var_dump($methodInfo->returnsReference());
1616

17-
$methodInfo = new ReflectionMethod('TestClass::bar');
17+
$methodInfo = ReflectionMethod::createFromMethodName('TestClass::bar');
1818
var_dump($methodInfo->returnsReference());
1919

2020
?>

‎ext/reflection/tests/bug60367.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ class B extends A {
1818

1919
}
2020

21-
$method = new ReflectionMethod("b::call");
21+
$method = ReflectionMethod::createFromMethodName("b::call");
2222
$method->invoke(null);
2323
$method->invokeArgs(null, array());
24-
$method = new ReflectionMethod("A::call");
24+
$method = ReflectionMethod::createFromMethodName("A::call");
2525
$method->invoke(null);
2626
$method->invokeArgs(null, array());
2727
?>

‎ext/reflection/tests/parameters_002.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function check_params($r)
6969

7070
check_params(new ReflectionFunction('test'));
7171

72-
check_params(new ReflectionMethod('test::method'));
72+
check_params(ReflectionMethod::createFromMethodName('test::method'));
7373

7474
?>
7575
--EXPECTF--

0 commit comments

Comments
 (0)