Skip to content

Commit abb5d54

Browse files
committed
Fix re-binding of inner closure, fix test
1 parent 04e9b0f commit abb5d54

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

Zend/tests/partial_application/rebinding_003.phpt

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,66 @@ Rebinding PFA of Closure rebinds inner Closure
44
<?php
55

66
class C {
7-
function f($a) { var_dump($this, $this === $a); }
8-
static function g($a) { var_dump(static::class); }
7+
function getF() {
8+
return function ($a) { var_dump($this, $this === $a); };
9+
}
10+
function getG() {
11+
return static function ($a) { var_dump(static::class, $a); };
12+
}
913
}
1014

1115
class SubClass extends C {}
1216

1317
class Unrelated {}
1418

1519
$c = new C();
16-
$f = $c->f(?);
17-
$g = $c->g(?);
20+
$f = $c->getF()(?);
21+
$g = $c->getG()(?);
1822

1923
echo "# Can be rebound to \$this of the same class:\n";
20-
$f->bindTo(new C)($c);
24+
$d = new C();
25+
$f->bindTo($d)($d);
2126

2227
echo "# Can be rebound to \$this of a sub-class:\n";
23-
$f->bindTo(new SubClass)($c);
28+
$d = new SubClass();
29+
$f->bindTo($d)($d);
2430

2531
echo "# Cannot be rebound to an unrelated class:\n";
2632
try {
2733
$f->bindTo(new Unrelated)($c);
2834
} catch (Error $e) {
29-
echo $e->getMessage(), "\n";
35+
echo $e::class, ": ", $e->getMessage(), "\n";
3036
}
3137

32-
echo "# Cannot unbind \$this on instance method:\n";
38+
echo "# Cannot unbind \$this on non-static closure:\n";
3339
try {
3440
$f->bindTo(null)($c);
3541
} catch (Error $e) {
36-
echo $e->getMessage(), "\n";
42+
echo $e::class, ": ", $e->getMessage(), "\n";
3743
}
3844

39-
echo "# Can unbind \$this on static method:\n";
45+
echo "# Can unbind \$this on static closure:\n";
4046
$g->bindTo(null)($c);
4147

4248
?>
4349
--EXPECTF--
4450
# Can be rebound to $this of the same class:
4551
object(C)#%d (0) {
4652
}
47-
bool(false)
53+
bool(true)
4854
# Can be rebound to $this of a sub-class:
4955
object(SubClass)#%d (0) {
5056
}
51-
bool(false)
57+
bool(true)
5258
# Cannot be rebound to an unrelated class:
5359

5460
Warning: Cannot bind method C::{closure:%s:%d}() to object of class Unrelated, this will be an error in PHP 9 in %s on line %d
55-
Value of type null is not callable
56-
# Cannot unbind $this on instance method:
61+
Error: Value of type null is not callable
62+
# Cannot unbind $this on non-static closure:
5763

5864
Warning: Cannot unbind $this of method, this will be an error in PHP 9 in %s on line %d
59-
Value of type null is not callable
60-
# Can unbind $this on static method:
65+
Error: Value of type null is not callable
66+
# Can unbind $this on static closure:
6167
string(1) "C"
68+
object(C)#%d (0) {
69+
}

Zend/zend_closures.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ static zend_result do_closure_bind(zval *return_value, zval *zclosure, zval *new
272272
if (ZEND_CLOSURE_FLAGS(closure) & ZEND_PARTIAL_OF_CLOSURE) {
273273
/* Re-bind the inner closure */
274274

275+
closure = (zend_closure*)Z_OBJ_P(return_value);
275276
HashTable *static_variables = ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
276277
ZEND_ASSERT(static_variables->nNumOfElements > 0);
277278
zval *inner = &static_variables->arData[0].val;

0 commit comments

Comments
 (0)