mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Refactor ReflectionMethod::__construct()
Closes GH-6098
This commit is contained in:
parent
f33fd9b7fe
commit
a59923befd
7 changed files with 76 additions and 75 deletions
|
@ -2976,81 +2976,83 @@ ZEND_METHOD(ReflectionUnionType, getTypes)
|
||||||
/* {{{ Constructor. Throws an Exception in case the given method does not exist */
|
/* {{{ Constructor. Throws an Exception in case the given method does not exist */
|
||||||
ZEND_METHOD(ReflectionMethod, __construct)
|
ZEND_METHOD(ReflectionMethod, __construct)
|
||||||
{
|
{
|
||||||
zval *classname;
|
zend_object *arg1_obj;
|
||||||
zval *object, *orig_obj;
|
zend_string *arg1_str;
|
||||||
reflection_object *intern;
|
zend_string *arg2_str = NULL;
|
||||||
char *lcname;
|
|
||||||
zend_class_entry *ce;
|
|
||||||
zend_function *mptr;
|
|
||||||
char *name_str, *tmp;
|
|
||||||
size_t name_len, tmp_len;
|
|
||||||
zval ztmp;
|
|
||||||
|
|
||||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "zs", &classname, &name_str, &name_len) == FAILURE) {
|
zend_object *orig_obj = NULL;
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
|
zend_class_entry *ce = NULL;
|
||||||
|
zend_string *class_name = NULL;
|
||||||
|
char *method_name;
|
||||||
|
size_t method_name_len;
|
||||||
|
char *lcname;
|
||||||
|
|
||||||
|
zval *object;
|
||||||
|
reflection_object *intern;
|
||||||
|
zend_function *mptr;
|
||||||
|
|
||||||
|
ZEND_PARSE_PARAMETERS_START(1, 2)
|
||||||
|
Z_PARAM_STR_OR_OBJ(arg1_str, arg1_obj)
|
||||||
|
Z_PARAM_OPTIONAL
|
||||||
|
Z_PARAM_STR_OR_NULL(arg2_str)
|
||||||
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
|
||||||
|
if (arg1_obj) {
|
||||||
|
if (!arg2_str) {
|
||||||
|
zend_argument_value_error(2, "cannot be null when argument #1 ($objectOrMethod) is an object");
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tmp = strstr(name_str, "::")) == NULL) {
|
orig_obj = arg1_obj;
|
||||||
|
ce = arg1_obj->ce;
|
||||||
|
method_name = ZSTR_VAL(arg2_str);
|
||||||
|
method_name_len = ZSTR_LEN(arg2_str);
|
||||||
|
} else if (arg2_str) {
|
||||||
|
class_name = zend_string_copy(arg1_str);
|
||||||
|
method_name = ZSTR_VAL(arg2_str);
|
||||||
|
method_name_len = ZSTR_LEN(arg2_str);
|
||||||
|
} else {
|
||||||
|
char *tmp;
|
||||||
|
size_t tmp_len;
|
||||||
|
char *name = ZSTR_VAL(arg1_str);
|
||||||
|
|
||||||
|
if ((tmp = strstr(name, "::")) == NULL) {
|
||||||
zend_argument_error(reflection_exception_ptr, 1, "must be a valid method name");
|
zend_argument_error(reflection_exception_ptr, 1, "must be a valid method name");
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
classname = &ztmp;
|
tmp_len = tmp - name;
|
||||||
tmp_len = tmp - name_str;
|
|
||||||
ZVAL_STRINGL(classname, name_str, tmp_len);
|
class_name = zend_string_init(name, tmp_len, 0);
|
||||||
name_len = name_len - (tmp_len + 2);
|
method_name = tmp + 2;
|
||||||
name_str = tmp + 2;
|
method_name_len = ZSTR_LEN(arg1_str) - tmp_len - 2;
|
||||||
orig_obj = NULL;
|
}
|
||||||
} else if (Z_TYPE_P(classname) == IS_OBJECT) {
|
|
||||||
orig_obj = classname;
|
if (class_name) {
|
||||||
} else {
|
if ((ce = zend_lookup_class(class_name)) == NULL) {
|
||||||
orig_obj = NULL;
|
if (!EG(exception)) {
|
||||||
|
zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(class_name));
|
||||||
|
}
|
||||||
|
zend_string_release(class_name);
|
||||||
|
RETURN_THROWS();
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_string_release(class_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
object = ZEND_THIS;
|
object = ZEND_THIS;
|
||||||
intern = Z_REFLECTION_P(object);
|
intern = Z_REFLECTION_P(object);
|
||||||
|
|
||||||
switch (Z_TYPE_P(classname)) {
|
lcname = zend_str_tolower_dup(method_name, method_name_len);
|
||||||
case IS_STRING:
|
|
||||||
if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) {
|
|
||||||
if (!EG(exception)) {
|
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
|
||||||
"Class \"%s\" does not exist", Z_STRVAL_P(classname));
|
|
||||||
}
|
|
||||||
if (classname == &ztmp) {
|
|
||||||
zval_ptr_dtor_str(&ztmp);
|
|
||||||
}
|
|
||||||
RETURN_THROWS();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IS_OBJECT:
|
if (ce == zend_ce_closure && orig_obj && (method_name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
|
||||||
ce = Z_OBJCE_P(classname);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (classname == &ztmp) {
|
|
||||||
zval_ptr_dtor_str(&ztmp);
|
|
||||||
}
|
|
||||||
zend_argument_error(reflection_exception_ptr, 1, "must be of type object|string, %s given", zend_zval_type_name(classname));
|
|
||||||
RETURN_THROWS();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classname == &ztmp) {
|
|
||||||
zval_ptr_dtor_str(&ztmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
lcname = zend_str_tolower_dup(name_str, name_len);
|
|
||||||
|
|
||||||
if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
|
|
||||||
&& memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
&& memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
|
||||||
&& (mptr = zend_get_closure_invoke_method(Z_OBJ_P(orig_obj))) != NULL)
|
&& (mptr = zend_get_closure_invoke_method(orig_obj)) != NULL)
|
||||||
{
|
{
|
||||||
/* do nothing, mptr already set */
|
/* do nothing, mptr already set */
|
||||||
} else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, name_len)) == NULL) {
|
} else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, method_name_len)) == NULL) {
|
||||||
efree(lcname);
|
efree(lcname);
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
zend_throw_exception_ex(reflection_exception_ptr, 0,
|
||||||
"Method %s::%s() does not exist", ZSTR_VAL(ce->name), name_str);
|
"Method %s::%s() does not exist", ZSTR_VAL(ce->name), method_name);
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
efree(lcname);
|
efree(lcname);
|
||||||
|
|
|
@ -147,8 +147,7 @@ final class ReflectionGenerator
|
||||||
|
|
||||||
class ReflectionMethod extends ReflectionFunctionAbstract
|
class ReflectionMethod extends ReflectionFunctionAbstract
|
||||||
{
|
{
|
||||||
/** @param object|string $objectOrMethod */
|
public function __construct(object|string $objectOrMethod, ?string $method = null) {}
|
||||||
public function __construct($objectOrMethod, string $method = UNKNOWN) {}
|
|
||||||
|
|
||||||
public function __toString(): string {}
|
public function __toString(): string {}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* This is a generated file, edit the .stub.php file instead.
|
/* This is a generated file, edit the .stub.php file instead.
|
||||||
* Stub hash: 1311fc5c498d6f16afb5a18aee2d60e72048174f */
|
* Stub hash: d698afd338e4bf7c782f0edddfcbe95859eef477 */
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1)
|
||||||
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
|
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
|
||||||
|
@ -101,8 +101,8 @@ ZEND_END_ARG_INFO()
|
||||||
#define arginfo_class_ReflectionGenerator_getExecutingGenerator arginfo_class_ReflectionFunctionAbstract___clone
|
#define arginfo_class_ReflectionGenerator_getExecutingGenerator arginfo_class_ReflectionFunctionAbstract___clone
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionMethod___construct, 0, 0, 1)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionMethod___construct, 0, 0, 1)
|
||||||
ZEND_ARG_INFO(0, objectOrMethod)
|
ZEND_ARG_TYPE_MASK(0, objectOrMethod, MAY_BE_OBJECT|MAY_BE_STRING, NULL)
|
||||||
ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0)
|
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, method, IS_STRING, 1, "null")
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
#define arginfo_class_ReflectionMethod___toString arginfo_class_ReflectionFunction___toString
|
#define arginfo_class_ReflectionMethod___toString arginfo_class_ReflectionFunction___toString
|
||||||
|
|
|
@ -34,6 +34,6 @@ string(24) "Class "a" does not exist"
|
||||||
string(23) "Class "" does not exist"
|
string(23) "Class "" does not exist"
|
||||||
string(24) "Class "a" does not exist"
|
string(24) "Class "a" does not exist"
|
||||||
string(23) "Class "" does not exist"
|
string(23) "Class "" does not exist"
|
||||||
string(103) "ReflectionMethod::__construct(): Argument #1 ($objectOrMethod) must be of type object|string, int given"
|
string(24) "Class "1" does not exist"
|
||||||
string(23) "Class "" does not exist"
|
string(23) "Class "" does not exist"
|
||||||
Done
|
Done
|
||||||
|
|
|
@ -8,16 +8,16 @@ Steve Seear <stevseea@php.net>
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new ReflectionMethod();
|
new ReflectionMethod();
|
||||||
} catch (TypeError $re) {
|
} catch (ArgumentCountError $re) {
|
||||||
echo "Ok - ".$re->getMessage().PHP_EOL;
|
echo "Ok - ".$re->getMessage().PHP_EOL;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new ReflectionMethod('a', 'b', 'c');
|
new ReflectionMethod('a', 'b', 'c');
|
||||||
} catch (TypeError $re) {
|
} catch (ArgumentCountError $re) {
|
||||||
echo "Ok - ".$re->getMessage().PHP_EOL;
|
echo "Ok - ".$re->getMessage().PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Ok - ReflectionMethod::__construct() expects exactly 1 argument, 0 given
|
Ok - ReflectionMethod::__construct() expects at least 1 argument, 0 given
|
||||||
Ok - ReflectionMethod::__construct() expects exactly 1 argument, 3 given
|
Ok - ReflectionMethod::__construct() expects at most 2 arguments, 3 given
|
||||||
|
|
|
@ -75,9 +75,9 @@ Stack trace:
|
||||||
#0 %s ReflectionMethod->__construct('3')
|
#0 %s ReflectionMethod->__construct('3')
|
||||||
#1 {main}
|
#1 {main}
|
||||||
Wrong type of argument (bool, string):
|
Wrong type of argument (bool, string):
|
||||||
ReflectionException: ReflectionMethod::__construct(): Argument #1 ($objectOrMethod) must be of type object|string, bool given in %s:%d
|
ReflectionException: Class "1" does not exist in %s:%d
|
||||||
Stack trace:
|
Stack trace:
|
||||||
#0 %s ReflectionMethod->__construct(true, 'foo')
|
#0 %s ReflectionMethod->__construct('1', 'foo')
|
||||||
#1 {main}
|
#1 {main}
|
||||||
Wrong type of argument (string, bool):
|
Wrong type of argument (string, bool):
|
||||||
ReflectionException: Method TestClass::1() does not exist in %s:%d
|
ReflectionException: Method TestClass::1() does not exist in %s:%d
|
||||||
|
|
|
@ -16,13 +16,13 @@ class TestClass
|
||||||
try {
|
try {
|
||||||
echo "Too few arguments:\n";
|
echo "Too few arguments:\n";
|
||||||
$methodInfo = new ReflectionMethod();
|
$methodInfo = new ReflectionMethod();
|
||||||
} catch (TypeError $re) {
|
} catch (ArgumentCountError $re) {
|
||||||
echo "Ok - ".$re->getMessage().PHP_EOL;
|
echo "Ok - ".$re->getMessage().PHP_EOL;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
echo "\nToo many arguments:\n";
|
echo "\nToo many arguments:\n";
|
||||||
$methodInfo = new ReflectionMethod("TestClass", "foo", true);
|
$methodInfo = new ReflectionMethod("TestClass", "foo", true);
|
||||||
} catch (TypeError $re) {
|
} catch (ArgumentCountError $re) {
|
||||||
echo "Ok - ".$re->getMessage().PHP_EOL;
|
echo "Ok - ".$re->getMessage().PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ try {
|
||||||
try {
|
try {
|
||||||
//invalid 1st param
|
//invalid 1st param
|
||||||
$methodInfo = new ReflectionMethod([], "foo");
|
$methodInfo = new ReflectionMethod([], "foo");
|
||||||
} catch (ReflectionException $re) {
|
} catch (TypeError $re) {
|
||||||
echo "Ok - ".$re->getMessage().PHP_EOL;
|
echo "Ok - ".$re->getMessage().PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,10 @@ try{
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Too few arguments:
|
Too few arguments:
|
||||||
Ok - ReflectionMethod::__construct() expects exactly 1 argument, 0 given
|
Ok - ReflectionMethod::__construct() expects at least 1 argument, 0 given
|
||||||
|
|
||||||
Too many arguments:
|
Too many arguments:
|
||||||
Ok - ReflectionMethod::__construct() expects exactly 1 argument, 3 given
|
Ok - ReflectionMethod::__construct() expects at most 2 arguments, 3 given
|
||||||
Ok - Class "InvalidClassName" does not exist
|
Ok - Class "InvalidClassName" does not exist
|
||||||
Ok - ReflectionMethod::__construct(): Argument #1 ($objectOrMethod) must be of type object|string, array given
|
Ok - ReflectionMethod::__construct(): Argument #1 ($objectOrMethod) must be of type object|string, array given
|
||||||
Ok - ReflectionMethod::__construct() expects exactly 1 argument, 2 given
|
Ok - ReflectionMethod::__construct(): Argument #2 ($method) must be of type ?string, array given
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue