mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Don't implicitly make closures in static methods static
It makes no sense that you can't write a closure using $this in a static method, even though you can write one outside a class. Now only closures that have been marked as static will be considered to be static. Fixes bug #65598.
This commit is contained in:
parent
d1363e30fd
commit
bc2ff4a299
4 changed files with 9 additions and 17 deletions
|
@ -49,7 +49,7 @@ $d = $staticUnscoped->bindTo(null); $d(); echo "\n";
|
|||
$d = $nonstaticUnscoped->bindTo(null); $d(); echo "\n";
|
||||
$d = $staticScoped->bindTo(null); $d(); echo "\n";
|
||||
$d = $nonstaticScoped->bindTo(null); $d(); echo "\n";
|
||||
//$d should have been turned to static
|
||||
// $d is still non-static
|
||||
$d->bindTo($d);
|
||||
|
||||
echo "After binding, with same-class instance for the bound ones", "\n";
|
||||
|
@ -83,8 +83,6 @@ scoped to A: bool(true)
|
|||
bound: no
|
||||
scoped to A: bool(true)
|
||||
bound: no
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
After binding, with same-class instance for the bound ones
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
|
@ -103,4 +101,4 @@ scoped to A: bool(false)
|
|||
bound: B (should be scoped to dummy class)
|
||||
scoped to A: bool(true)
|
||||
bound: B
|
||||
Done.
|
||||
Done.
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
--TEST--
|
||||
Closure 045: Closures created in static methods are static, even without the keyword
|
||||
Closure 045: Closures created in static methods are not implicitly static
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
static function foo() {
|
||||
return function () {};
|
||||
}
|
||||
static function foo() {
|
||||
return function () {};
|
||||
}
|
||||
}
|
||||
|
||||
$a = A::foo();
|
||||
|
@ -15,5 +15,4 @@ $a->bindTo(new A);
|
|||
echo "Done.\n";
|
||||
|
||||
--EXPECTF--
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
Done.
|
||||
|
|
|
@ -27,7 +27,7 @@ $nonstaticScoped(); echo "\n";
|
|||
echo "After binding, no instance", "\n";
|
||||
$d = $nonstaticUnscoped->bindTo(null, "static"); $d(); echo "\n";
|
||||
$d = $nonstaticScoped->bindTo(null, "static"); $d(); echo "\n";
|
||||
//$d should have been turned to static
|
||||
// $d is still non-static
|
||||
$d->bindTo($d);
|
||||
|
||||
echo "After binding, with same-class instance for the bound one", "\n";
|
||||
|
@ -54,8 +54,6 @@ bool(false)
|
|||
bool(true)
|
||||
bool(false)
|
||||
|
||||
|
||||
Warning: Cannot bind an instance to a static closure in %s on line %d
|
||||
After binding, with same-class instance for the bound one
|
||||
bool(false)
|
||||
bool(true)
|
||||
|
|
|
@ -513,17 +513,14 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
|||
}
|
||||
|
||||
ZVAL_UNDEF(&closure->this_ptr);
|
||||
/* Invariants:
|
||||
* If the closure is unscoped, it has no bound object.
|
||||
* The the closure is scoped, it's either static or it's bound */
|
||||
/* Invariant:
|
||||
* If the closure is unscoped or static, it has no bound object. */
|
||||
closure->func.common.scope = scope;
|
||||
closure->called_scope = called_scope;
|
||||
if (scope) {
|
||||
closure->func.common.fn_flags |= ZEND_ACC_PUBLIC;
|
||||
if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
|
||||
ZVAL_COPY(&closure->this_ptr, this_ptr);
|
||||
} else {
|
||||
closure->func.common.fn_flags |= ZEND_ACC_STATIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue