Skip to content

Deprecate partially supported callables #7446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Zend/tests/bug37138.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion Zend/tests/bug41026.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 5 additions & 1 deletion Zend/tests/bug45186.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ try {
}

?>
--EXPECT--
--EXPECTF--
__call:
string(3) "ABC"
__call:
Expand All @@ -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
Expand Down
6 changes: 5 additions & 1 deletion Zend/tests/bug45186_2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ try {
}

?>
--EXPECT--
--EXPECTF--
__call:
string(3) "ABC"
__call:
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion Zend/tests/bug48770.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 8 additions & 1 deletion Zend/tests/bug48770_2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
7 changes: 6 additions & 1 deletion Zend/tests/bug48770_3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
6 changes: 5 additions & 1 deletion Zend/tests/bug66719.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
3 changes: 2 additions & 1 deletion Zend/tests/bug78770.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ class Test {

?>
===DONE===
--EXPECT--
--EXPECTF--
Deprecated: Use of "self" in callables is deprecated in %s on line %d
===DONE===
8 changes: 6 additions & 2 deletions Zend/tests/bug78898.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 69 additions & 0 deletions Zend/tests/callable_self_parent_static_deprecation.phpt
Original file line number Diff line number Diff line change
@@ -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
18 changes: 13 additions & 5 deletions Zend/tests/closures/closure_from_callable_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
4 changes: 3 additions & 1 deletion Zend/tests/closures/closure_from_callable_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
3 changes: 2 additions & 1 deletion Zend/tests/lsb_011.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion Zend/tests/lsb_012.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 9 additions & 1 deletion Zend/tests/lsb_021.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,20 @@ C::testForward();
C::testNoForward();

?>
--EXPECT--
--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
Expand Down
17 changes: 16 additions & 1 deletion Zend/tests/lsb_022.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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
20 changes: 17 additions & 3 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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. */
Expand Down Expand Up @@ -3756,7 +3770,7 @@ ZEND_API bool zend_is_callable_at_frame(
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 {
Expand Down
2 changes: 2 additions & 0 deletions ext/pdo_mysql/tests/pdo_mysql_subclass.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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)')
Expand Down
Loading