From ee510eed685cee62cd99a210e27bdee6892861e3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 1 Sep 2021 16:54:17 +0200 Subject: [PATCH] Deprecate partially supported callables This deprecates all callables that are accepted by call_user_func($callable) but not by $callable(). In particular: "self::method" "parent::method" "static::method" ["self", "method"] ["parent", "method"] ["static", "method"] ["Foo", "Bar::method"] [new Foo, "Bar::method"] RFC: https://wiki.php.net/rfc/deprecate_partially_supported_callables Closes GH-7446. --- UPGRADING | 20 ++++++ Zend/tests/bug37138.phpt | 6 +- Zend/tests/bug41026.phpt | 3 +- Zend/tests/bug45186.phpt | 6 +- Zend/tests/bug45186_2.phpt | 6 +- Zend/tests/bug48770.phpt | 3 +- Zend/tests/bug48770_2.phpt | 9 ++- Zend/tests/bug48770_3.phpt | 7 +- Zend/tests/bug66719.phpt | 6 +- Zend/tests/bug78770.phpt | 3 +- Zend/tests/bug78898.phpt | 8 ++- ...llable_self_parent_static_deprecation.phpt | 69 +++++++++++++++++++ .../closures/closure_from_callable_basic.phpt | 18 +++-- .../closures/closure_from_callable_error.phpt | 4 +- Zend/tests/lsb_011.phpt | 3 +- Zend/tests/lsb_012.phpt | 3 +- Zend/tests/lsb_021.phpt | 14 +++- Zend/tests/lsb_022.phpt | 17 ++++- Zend/zend_API.c | 20 +++++- ext/pdo_mysql/tests/pdo_mysql_subclass.phpt | 2 + ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt | 2 + ext/spl/tests/bug65006.phpt | 5 +- .../class_object/forward_static_call_001.phpt | 12 +++- .../class_object/forward_static_call_003.phpt | 6 +- .../tests/general_functions/bug40398.phpt | 9 ++- .../general_functions/callbacks_001.phpt | 16 ++++- tests/classes/abstract_user_call.phpt | 4 +- 27 files changed, 249 insertions(+), 32 deletions(-) create mode 100644 Zend/tests/callable_self_parent_static_deprecation.phpt diff --git a/UPGRADING b/UPGRADING index 699aa55c803..6b2efba9fd3 100644 --- a/UPGRADING +++ b/UPGRADING @@ -35,6 +35,26 @@ PHP 8.2 UPGRADE NOTES 4. Deprecated Functionality ======================================== +- Core: + . Callables that are not accepted by the $callable() syntax (but are accepted + by call_user_func) are deprecated. In particular: + + "self::method" + "parent::method" + "static::method" + ["self", "method"] + ["parent", "method"] + ["static", "method"] + ["Foo", "Bar::method"] + [new Foo, "Bar::method"] + + This does not affect normal method callables like "A::method" or + ["A", "method"]. A deprecation notice is only emitted on call. Both + is_callable() and the callable type will silently accept these callables + until support for them is removed entirely. + + RFC: https://wiki.php.net/rfc/deprecate_partially_supported_callables + ======================================== 5. Changed Functions ======================================== diff --git a/Zend/tests/bug37138.phpt b/Zend/tests/bug37138.phpt index 67dfa987daa..ce0a23e3205 100644 --- a/Zend/tests/bug37138.phpt +++ b/Zend/tests/bug37138.phpt @@ -14,7 +14,11 @@ st::e (); st::e2 (); stch::g (); ?> ---EXPECT-- +--EXPECTF-- EHLO + +Deprecated: Use of "self" in callables is deprecated in %s on line %d EHLO + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d EHLO diff --git a/Zend/tests/bug41026.phpt b/Zend/tests/bug41026.phpt index 36d8ba4c634..ae297e4e4ba 100644 --- a/Zend/tests/bug41026.phpt +++ b/Zend/tests/bug41026.phpt @@ -20,6 +20,7 @@ try_class::main (); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Use of "self" in callables is deprecated in %s on line %d Done CHECKPOINT diff --git a/Zend/tests/bug45186.phpt b/Zend/tests/bug45186.phpt index 46ec78ee1b4..9e0078d7700 100644 --- a/Zend/tests/bug45186.phpt +++ b/Zend/tests/bug45186.phpt @@ -38,7 +38,7 @@ try { } ?> ---EXPECT-- +--EXPECTF-- __call: string(3) "ABC" __call: @@ -47,8 +47,12 @@ __call: string(3) "xyz" __call: string(3) "www" + +Deprecated: Use of "self" in callables is deprecated in %s on line %d __call: string(1) "y" + +Deprecated: Use of "self" in callables is deprecated in %s on line %d __call: string(1) "y" ok diff --git a/Zend/tests/bug45186_2.phpt b/Zend/tests/bug45186_2.phpt index 18a0799716b..e85528ce8b0 100644 --- a/Zend/tests/bug45186_2.phpt +++ b/Zend/tests/bug45186_2.phpt @@ -38,7 +38,7 @@ try { } ?> ---EXPECT-- +--EXPECTF-- __call: string(3) "ABC" __call: @@ -47,8 +47,12 @@ __call: string(3) "xyz" __call: string(3) "www" + +Deprecated: Use of "self" in callables is deprecated in %s on line %d __call: string(1) "y" + +Deprecated: Use of "self" in callables is deprecated in %s on line %d __call: string(1) "y" ok diff --git a/Zend/tests/bug48770.phpt b/Zend/tests/bug48770.phpt index 13ff963d067..f6188c60953 100644 --- a/Zend/tests/bug48770.phpt +++ b/Zend/tests/bug48770.phpt @@ -30,5 +30,6 @@ $c = new C; $c->callFuncInParent('Which function will be called??'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Callables of the form ["C", "parent::func"] are deprecated in %s on line %d B::func called diff --git a/Zend/tests/bug48770_2.phpt b/Zend/tests/bug48770_2.phpt index 9ba6776a5a0..14fe28cca23 100644 --- a/Zend/tests/bug48770_2.phpt +++ b/Zend/tests/bug48770_2.phpt @@ -53,8 +53,15 @@ $c = new C; $c->func('This should work!'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Callables of the form ["C", "parent::func2"] are deprecated in %s on line %d string(27) "B::func2: This should work!" + +Deprecated: Callables of the form ["C", "parent::func3"] are deprecated in %s on line %d string(27) "B::func3: This should work!" + +Deprecated: Callables of the form ["C", "parent::func22"] are deprecated in %s on line %d call_user_func_array(): Argument #1 ($callback) must be a valid callback, cannot access private method B::func22() + +Deprecated: Callables of the form ["C", "parent::inexistent"] are deprecated in %s on line %d call_user_func_array(): Argument #1 ($callback) must be a valid callback, class B does not have a method "inexistent" diff --git a/Zend/tests/bug48770_3.phpt b/Zend/tests/bug48770_3.phpt index 8e5d6033572..98311eb8ece 100644 --- a/Zend/tests/bug48770_3.phpt +++ b/Zend/tests/bug48770_3.phpt @@ -44,7 +44,12 @@ $c = new C; $c->func('This should work!'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Callables of the form ["C", "self::func2"] are deprecated in %s on line %d string(27) "B::func2: This should work!" + +Deprecated: Callables of the form ["C", "self::func3"] are deprecated in %s on line %d string(27) "B::func3: This should work!" + +Deprecated: Callables of the form ["C", "self::inexistent"] are deprecated in %s on line %d call_user_func_array(): Argument #1 ($callback) must be a valid callback, class C does not have a method "inexistent" diff --git a/Zend/tests/bug66719.phpt b/Zend/tests/bug66719.phpt index 70785b4a784..3acff69ad48 100644 --- a/Zend/tests/bug66719.phpt +++ b/Zend/tests/bug66719.phpt @@ -34,10 +34,14 @@ call_user_func(array(B::class, 'parent::who')); C::test(); ?> ---EXPECT-- +--EXPECTF-- string(1) "B" string(1) "A" + +Deprecated: Callables of the form ["B", "parent::who"] are deprecated in %s on line %d string(1) "A" string(1) "B" string(1) "A" + +Deprecated: Callables of the form ["B", "parent::who"] are deprecated in %s on line %d string(1) "A" diff --git a/Zend/tests/bug78770.phpt b/Zend/tests/bug78770.phpt index 0c051cd59b8..dc8255c05ab 100644 --- a/Zend/tests/bug78770.phpt +++ b/Zend/tests/bug78770.phpt @@ -19,5 +19,6 @@ class Test { ?> ===DONE=== ---EXPECT-- +--EXPECTF-- +Deprecated: Use of "self" in callables is deprecated in %s on line %d ===DONE=== diff --git a/Zend/tests/bug78898.phpt b/Zend/tests/bug78898.phpt index 248195e551e..f640c5687c7 100644 --- a/Zend/tests/bug78898.phpt +++ b/Zend/tests/bug78898.phpt @@ -30,5 +30,9 @@ $b = new B; $b->x(); ?> ---EXPECT-- -aaa +--EXPECTF-- +a +Deprecated: Use of "parent" in callables is deprecated in %s on line %d +a +Deprecated: Use of "parent" in callables is deprecated in %s on line %d +a diff --git a/Zend/tests/callable_self_parent_static_deprecation.phpt b/Zend/tests/callable_self_parent_static_deprecation.phpt new file mode 100644 index 00000000000..a6696d234bc --- /dev/null +++ b/Zend/tests/callable_self_parent_static_deprecation.phpt @@ -0,0 +1,69 @@ +--TEST-- +Deprecation of self/parent/static in callables +--FILE-- +callableTypeHint("self::foo"); + } + + public function callableTypeHint(callable $c) {} +} + +$b = new B; +$b->test(); + +?> +--EXPECTF-- +Test different callables + +Deprecated: Use of "self" in callables is deprecated in %s on line %d + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d + +Deprecated: Use of "static" in callables is deprecated in %s on line %d + +Deprecated: Use of "self" in callables is deprecated in %s on line %d + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d + +Deprecated: Use of "static" in callables is deprecated in %s on line %d + +Deprecated: Callables of the form ["B", "self::foo"] are deprecated in %s on line %d + +Deprecated: Callables of the form ["B", "parent::foo"] are deprecated in %s on line %d + +Deprecated: Callables of the form ["B", "static::foo"] are deprecated in %s on line %d + +Deprecated: Callables of the form ["B", "A::foo"] are deprecated in %s on line %d +Test array_map() + +Deprecated: Use of "self" in callables is deprecated in %s on line %d +Test is_callable() -- should be silent +bool(true) +Test callable type hint -- should be silent diff --git a/Zend/tests/closures/closure_from_callable_basic.phpt b/Zend/tests/closures/closure_from_callable_basic.phpt index 88a27c7e703..7c7fdf5a288 100644 --- a/Zend/tests/closures/closure_from_callable_basic.phpt +++ b/Zend/tests/closures/closure_from_callable_basic.phpt @@ -96,7 +96,7 @@ echo $fn(" OK".PHP_EOL); ?> ---EXPECT-- +--EXPECTF-- Access public static function OK Access public static function with different case OK Access public static function with colon scheme OK @@ -111,9 +111,17 @@ Instance return private static method as callable OK Instance return protected static method as callable OK Subclass closure over parent class protected method OK Subclass closure over parent class static protected method OK -Access public instance method of parent object through "parent::" OK -Access public instance method of self object through "self::" OK -Access public instance method of parent object through "self::" to parent method OK -Access protected instance method of parent object through "self::" to parent method OK +Access public instance method of parent object through "parent::" +Deprecated: Use of "parent" in callables is deprecated in %s on line %d + OK +Access public instance method of self object through "self::" +Deprecated: Use of "self" in callables is deprecated in %s on line %d + OK +Access public instance method of parent object through "self::" to parent method +Deprecated: Use of "self" in callables is deprecated in %s on line %d + OK +Access protected instance method of parent object through "self::" to parent method +Deprecated: Use of "self" in callables is deprecated in %s on line %d + OK MagicCall __call instance method __call,nonExistentMethod, OK MagicCall __callStatic static method __callStatic,nonExistentMethod, OK diff --git a/Zend/tests/closures/closure_from_callable_error.phpt b/Zend/tests/closures/closure_from_callable_error.phpt index 5d1e078c1ee..d30e4fcfa28 100644 --- a/Zend/tests/closures/closure_from_callable_error.phpt +++ b/Zend/tests/closures/closure_from_callable_error.phpt @@ -193,7 +193,7 @@ catch (\Throwable $t) { echo "OK\n"; ?> ---EXPECT-- +--EXPECTF-- Cannot access privateInstance method statically Cannot access privateInstance method statically with colon scheme Cannot access privateInstance method @@ -209,4 +209,6 @@ Subclass cannot closure over parant private static method Function scope cannot closure over protected instance method Function scope cannot closure over private instance method Access private instance method of parent object through "self::" to parent method + +Deprecated: Use of "self" in callables is deprecated in %s on line %d OK diff --git a/Zend/tests/lsb_011.phpt b/Zend/tests/lsb_011.phpt index 206f0cb9d04..0d0faeda803 100644 --- a/Zend/tests/lsb_011.phpt +++ b/Zend/tests/lsb_011.phpt @@ -19,5 +19,6 @@ class Test2 extends Test1 { } Test2::test(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Use of "static" in callables is deprecated in %s on line %d ok diff --git a/Zend/tests/lsb_012.phpt b/Zend/tests/lsb_012.phpt index 21ddff3524f..bf959a30fcb 100644 --- a/Zend/tests/lsb_012.phpt +++ b/Zend/tests/lsb_012.phpt @@ -19,5 +19,6 @@ class Test2 extends Test1 { } Test2::test(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Use of "static" in callables is deprecated in %s on line %d ok diff --git a/Zend/tests/lsb_021.phpt b/Zend/tests/lsb_021.phpt index 5694537a041..5583a9de1f5 100644 --- a/Zend/tests/lsb_021.phpt +++ b/Zend/tests/lsb_021.phpt @@ -39,12 +39,20 @@ C::testForward(); C::testNoForward(); ?> ---EXPECT-- -C -C +--EXPECTF-- +C + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d +C + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d C C + +Deprecated: Use of "self" in callables is deprecated in %s on line %d C + +Deprecated: Use of "self" in callables is deprecated in %s on line %d C A A diff --git a/Zend/tests/lsb_022.phpt b/Zend/tests/lsb_022.phpt index e2a405c53e4..6053c94f746 100644 --- a/Zend/tests/lsb_022.phpt +++ b/Zend/tests/lsb_022.phpt @@ -24,9 +24,24 @@ class B extends A { } B::foo(); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Use of "static" in callables is deprecated in %s on line %d B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d + +Deprecated: Use of "static" in callables is deprecated in %s on line %d B + +Deprecated: Use of "static" in callables is deprecated in %s on line %d B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d + +Deprecated: Use of "static" in callables is deprecated in %s on line %d B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d + +Deprecated: Use of "static" in callables is deprecated in %s on line %d B diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 12453a53e8d..245967d6788 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3291,7 +3291,7 @@ static zend_always_inline zend_class_entry *get_scope(zend_execute_data *frame) return frame && frame->func ? frame->func->common.scope : NULL; } -static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *scope, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool *strict_class, char **error) /* {{{ */ +static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *scope, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool *strict_class, char **error, bool suppress_deprecation) /* {{{ */ { bool ret = 0; zend_class_entry *ce; @@ -3307,6 +3307,9 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (!scope) { if (error) *error = estrdup("cannot access \"self\" when no class scope is active"); } else { + if (error && !suppress_deprecation) { + zend_error(E_DEPRECATED, "Use of \"self\" in callables is deprecated"); + } fcc->called_scope = zend_get_called_scope(frame); if (!fcc->called_scope || !instanceof_function(fcc->called_scope, scope)) { fcc->called_scope = scope; @@ -3323,6 +3326,9 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc } else if (!scope->parent) { if (error) *error = estrdup("cannot access \"parent\" when current class scope has no parent"); } else { + if (error && !suppress_deprecation) { + zend_error(E_DEPRECATED, "Use of \"parent\" in callables is deprecated"); + } fcc->called_scope = zend_get_called_scope(frame); if (!fcc->called_scope || !instanceof_function(fcc->called_scope, scope->parent)) { fcc->called_scope = scope->parent; @@ -3340,6 +3346,9 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (!called_scope) { if (error) *error = estrdup("cannot access \"static\" when no class scope is active"); } else { + if (error && !suppress_deprecation) { + zend_error(E_DEPRECATED, "Use of \"static\" in callables is deprecated"); + } fcc->called_scope = called_scope; fcc->calling_scope = called_scope; if (!fcc->object) { @@ -3472,7 +3481,7 @@ static zend_always_inline bool zend_is_callable_check_func(int check_flags, zval fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope; } strict_class = 1; - } else if (!zend_is_callable_check_class(cname, scope, frame, fcc, &strict_class, error)) { + } else if (!zend_is_callable_check_class(cname, scope, frame, fcc, &strict_class, error, ce_org != NULL)) { zend_string_release_ex(cname, 0); return 0; } @@ -3483,6 +3492,11 @@ static zend_always_inline bool zend_is_callable_check_func(int check_flags, zval if (error) zend_spprintf(error, 0, "class %s is not a subclass of %s", ZSTR_VAL(ce_org->name), ZSTR_VAL(fcc->calling_scope->name)); return 0; } + if (ce_org && error) { + zend_error(E_DEPRECATED, + "Callables of the form [\"%s\", \"%s\"] are deprecated", + ZSTR_VAL(ce_org->name), Z_STRVAL_P(callable)); + } mname = zend_string_init(Z_STRVAL_P(callable) + clen + 2, mlen, 0); } else if (ce_org) { /* Try to fetch find static method of given class. */ @@ -3756,7 +3770,7 @@ check_func: return 1; } - if (!zend_is_callable_check_class(Z_STR_P(obj), get_scope(frame), frame, fcc, &strict_class, error)) { + if (!zend_is_callable_check_class(Z_STR_P(obj), get_scope(frame), frame, fcc, &strict_class, error, false)) { return 0; } } else { diff --git a/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt b/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt index 3bc6faf33fb..8ac1220e9e2 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt @@ -78,6 +78,8 @@ $db->exec('DROP TABLE IF EXISTS test'); ?> --EXPECTF-- __construct('%S', '%S', %s) + +Deprecated: Callables of the form ["MyPDO", "parent::__construct"] are deprecated in %s on line %d exec('DROP TABLE IF EXISTS test') exec('CREATE TABLE test(id INT)') exec('INSERT INTO test(id) VALUES (1), (2)') diff --git a/ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt b/ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt index e16ac67c6bc..5a5b728a5e6 100644 --- a/ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt +++ b/ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt @@ -126,6 +126,8 @@ function "" not found or invalid function name PDOStatement::fetchAll(): Argument #2 must be a callable, null given no array or string given cannot access "self" when no class scope is active + +Deprecated: Callables of the form ["bar", "parent::method"] are deprecated in %s on line %d array(2) { [0]=> string(9) "--- 1 ---" diff --git a/ext/spl/tests/bug65006.phpt b/ext/spl/tests/bug65006.phpt index 954811a7848..27d150383a2 100644 --- a/ext/spl/tests/bug65006.phpt +++ b/ext/spl/tests/bug65006.phpt @@ -22,7 +22,10 @@ second::init(); var_dump(spl_autoload_functions()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Use of "self" in callables is deprecated in %s on line %d + +Deprecated: Use of "self" in callables is deprecated in %s on line %d array(2) { [0]=> array(2) { diff --git a/ext/standard/tests/class_object/forward_static_call_001.phpt b/ext/standard/tests/class_object/forward_static_call_001.phpt index 30459f0c435..aa1f34413a8 100644 --- a/ext/standard/tests/class_object/forward_static_call_001.phpt +++ b/ext/standard/tests/class_object/forward_static_call_001.phpt @@ -57,14 +57,20 @@ echo "-\n"; C::test3(); ?> ---EXPECT-- +--EXPECTF-- A - B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d B - B + +Deprecated: Use of "self" in callables is deprecated in %s on line %d B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d B - B @@ -74,7 +80,11 @@ C C - B + +Deprecated: Use of "self" in callables is deprecated in %s on line %d B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d C - B diff --git a/ext/standard/tests/class_object/forward_static_call_003.phpt b/ext/standard/tests/class_object/forward_static_call_003.phpt index c2c0035f6bb..47f6b240396 100644 --- a/ext/standard/tests/class_object/forward_static_call_003.phpt +++ b/ext/standard/tests/class_object/forward_static_call_003.phpt @@ -38,12 +38,16 @@ echo "-\n"; C::test(); ?> ---EXPECT-- +--EXPECTF-- A - B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d B - C B + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d B diff --git a/ext/standard/tests/general_functions/bug40398.phpt b/ext/standard/tests/general_functions/bug40398.phpt index 274faf83086..a2fca18eb36 100644 --- a/ext/standard/tests/general_functions/bug40398.phpt +++ b/ext/standard/tests/general_functions/bug40398.phpt @@ -73,10 +73,17 @@ new Derived_5('5'); new Derived_6('6'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Callables of the form ["Derived_1", "Base::__construct"] are deprecated in %s on line %d Base::__construct(1) + +Deprecated: Callables of the form ["Derived_2", "parent::__construct"] are deprecated in %s on line %d Base::__construct(2) Base::__construct(3) + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d Base::__construct(4) Base::__construct(5) + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d Base::__construct(6) diff --git a/ext/standard/tests/general_functions/callbacks_001.phpt b/ext/standard/tests/general_functions/callbacks_001.phpt index 53e7dd914de..f173ca85161 100644 --- a/ext/standard/tests/general_functions/callbacks_001.phpt +++ b/ext/standard/tests/general_functions/callbacks_001.phpt @@ -83,14 +83,22 @@ $o = new P; $o->test(); ?> ---EXPECT-- +--EXPECTF-- parent|who + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d B C|parent::who + +Deprecated: Callables of the form ["C", "parent::who"] are deprecated in %s on line %d B B|parent::who + +Deprecated: Callables of the form ["B", "parent::who"] are deprecated in %s on line %d A E|parent::who + +Deprecated: Callables of the form ["E", "parent::who"] are deprecated in %s on line %d D A|who A @@ -100,10 +108,16 @@ B|who2 A ===FOREIGN=== parent|who + +Deprecated: Use of "parent" in callables is deprecated in %s on line %d O P|parent::who + +Deprecated: Callables of the form ["P", "parent::who"] are deprecated in %s on line %d O $this|O::who + +Deprecated: Callables of the form ["P", "O::who"] are deprecated in %s on line %d O $this|B::who call_user_func(): Argument #1 ($callback) must be a valid callback, class P is not a subclass of B diff --git a/tests/classes/abstract_user_call.phpt b/tests/classes/abstract_user_call.phpt index 312b43d4e46..a3e91967dff 100644 --- a/tests/classes/abstract_user_call.phpt +++ b/tests/classes/abstract_user_call.phpt @@ -27,6 +27,8 @@ try { } ?> ---EXPECT-- +--EXPECTF-- test::func() + +Deprecated: Callables of the form ["test", "test_base::func"] are deprecated in %s on line %d call_user_func(): Argument #1 ($callback) must be a valid callback, cannot call abstract method test_base::func()