mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
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.
This commit is contained in:
parent
1afe89f8c3
commit
ee510eed68
27 changed files with 249 additions and 32 deletions
20
UPGRADING
20
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
|
||||
========================================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -19,5 +19,6 @@ class Test {
|
|||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Deprecated: Use of "self" in callables is deprecated in %s on line %d
|
||||
===DONE===
|
||||
|
|
|
@ -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
|
||||
|
|
69
Zend/tests/callable_self_parent_static_deprecation.phpt
Normal file
69
Zend/tests/callable_self_parent_static_deprecation.phpt
Normal file
|
@ -0,0 +1,69 @@
|
|||
--TEST--
|
||||
Deprecation of self/parent/static in callables
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public function foo() {}
|
||||
}
|
||||
class B extends A {
|
||||
public function test() {
|
||||
// Different callables using self/parent/static
|
||||
echo "Test different callables\n";
|
||||
call_user_func("self::foo");
|
||||
call_user_func("parent::foo");
|
||||
call_user_func("static::foo");
|
||||
call_user_func(["self", "foo"]);
|
||||
call_user_func(["parent", "foo"]);
|
||||
call_user_func(["static", "foo"]);
|
||||
call_user_func(["B", "self::foo"]);
|
||||
call_user_func(["B", "parent::foo"]);
|
||||
call_user_func(["B", "static::foo"]);
|
||||
call_user_func(["B", "A::foo"]);
|
||||
|
||||
// Also applies to other things performing calls
|
||||
echo "Test array_map()\n";
|
||||
array_map("self::foo", [1]);
|
||||
|
||||
echo "Test is_callable() -- should be silent\n";
|
||||
var_dump(is_callable("self::foo"));
|
||||
|
||||
echo "Test callable type hint -- should be silent\n";
|
||||
$this->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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)')
|
||||
|
|
|
@ -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 ---"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue