Skip to content

Commit 7877389

Browse files
committed
Fix #74558: Can't rebind closure returned by Closure::fromCallable()
Failure to rebind such closures is not necessarily related to them being created by `ReflectionFunctionAbstract::getClosure()`, so we fix the error message. Closes GH-6424.
1 parent eda7492 commit 7877389

File tree

5 files changed

+22
-15
lines changed

5 files changed

+22
-15
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 7.4.14
44

5+
- Core:
6+
. Fixed bug #74558 (Can't rebind closure returned by Closure::fromCallable()).
7+
(cmb)
58

69
26 Nov 2020, PHP 7.4.13
710

Zend/tests/bug70630.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ $x = (new ReflectionFunction("substr"))->getClosure();
77
$x->call(new a);
88
?>
99
--EXPECTF--
10-
Warning: Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() in %s on line %d
10+
Warning: Cannot rebind scope of closure created from function in %s on line %d

Zend/tests/bug70685.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ var_dump($c);
1818
Warning: Cannot bind method SplDoublyLinkedList::count() to object of class cls in %s on line %d
1919
NULL
2020

21-
Warning: Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() in %s on line %d
21+
Warning: Cannot rebind scope of closure created from method in %s on line %d
2222
NULL

Zend/tests/closure_061.phpt

+12-12
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@ bindTo(new Cls, null):
118118
Success!
119119

120120
bindTo(new Cls, Cls::class):
121-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
121+
Cannot rebind scope of closure created from function
122122

123123
bindTo(null, Cls::class):
124-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
124+
Cannot rebind scope of closure created from function
125125

126126
bindTo(null, stdClass::class):
127127
Cannot bind closure to scope of internal class stdClass
@@ -139,10 +139,10 @@ bindTo(new Cls, null):
139139
Success!
140140

141141
bindTo(new Cls, Cls::class):
142-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
142+
Cannot rebind scope of closure created from function
143143

144144
bindTo(null, Cls::class):
145-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
145+
Cannot rebind scope of closure created from function
146146

147147
bindTo(null, stdClass::class):
148148
Cannot bind closure to scope of internal class stdClass
@@ -163,13 +163,13 @@ bindTo(new Cls, Cls::class):
163163
Cannot bind an instance to a static closure
164164

165165
bindTo(null, null):
166-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
166+
Cannot rebind scope of closure created from method
167167

168168
bindTo(null, ClsChild::class):
169-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
169+
Cannot rebind scope of closure created from method
170170

171171
bindTo(null, ClsUnrelated::class):
172-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
172+
Cannot rebind scope of closure created from method
173173

174174
(new Cls)->method()
175175
-------------------
@@ -189,13 +189,13 @@ bindTo(new ClsUnrelated, Cls::class):
189189
Cannot bind method Cls::method() to object of class ClsUnrelated
190190

191191
bindTo(new Cls, null):
192-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
192+
Cannot rebind scope of closure created from method
193193

194194
bindTo(new Cls, ClsUnrelated::class):
195-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
195+
Cannot rebind scope of closure created from method
196196

197197
bindTo(new Cls, ClsChild::class):
198-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
198+
Cannot rebind scope of closure created from method
199199

200200
(new SplDoublyLinkedList)->count()
201201
----------------------------------
@@ -216,10 +216,10 @@ bindTo(null, SplDoublyLinkedList::class):
216216
Cannot unbind $this of internal method
217217

218218
bindTo(new SplDoublyLinkedList, null):
219-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
219+
Cannot rebind scope of closure created from method
220220

221221
bindTo(new SplDoublyLinkedList, ClsUnrelated::class):
222-
Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()
222+
Cannot rebind scope of closure created from method
223223

224224
(function() {})()
225225
-----------------

Zend/zend_closures.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ static zend_bool zend_valid_closure_binding(
104104
}
105105

106106
if (is_fake_closure && scope != func->common.scope) {
107-
zend_error(E_WARNING, "Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure()");
107+
if (func->common.scope == NULL) {
108+
zend_error(E_WARNING, "Cannot rebind scope of closure created from function");
109+
} else {
110+
zend_error(E_WARNING, "Cannot rebind scope of closure created from method");
111+
}
108112
return 0;
109113
}
110114

0 commit comments

Comments
 (0)