diff options
-rw-r--r-- | Zend/tests/bug70685.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/closure_061.phpt | 208 |
2 files changed, 209 insertions, 1 deletions
diff --git a/Zend/tests/bug70685.phpt b/Zend/tests/bug70685.phpt index e286e58e7d..7a49ff1825 100644 --- a/Zend/tests/bug70685.phpt +++ b/Zend/tests/bug70685.phpt @@ -18,5 +18,5 @@ var_dump($c); Warning: Cannot bind internal method SplDoublyLinkedList::count() to object of class cls in %s on line %d NULL -Warning: Cannot bind function SplDoublyLinkedList::count to scope class cls in %s on line %d +Warning: Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() in %s on line %d NULL diff --git a/Zend/tests/closure_061.phpt b/Zend/tests/closure_061.phpt new file mode 100644 index 0000000000..a87303498e --- /dev/null +++ b/Zend/tests/closure_061.phpt @@ -0,0 +1,208 @@ +--TEST-- +Rebinding of ::getClosure()s +--FILE-- +<?php + +use SplDoublyLinkedList as DLL; + +function func($arg) { } + +class Cls { + public function method() {} + public static function staticMethod($arg) {} +} + +class ClsChild extends Cls {} + +class ClsUnrelated {} + +/* Format: [Function, [Obj, Scope]] */ +$tests = [ + ['func', [ + [null, null], + [new Cls, null], + [new Cls, 'Cls'], + [null, 'Cls'], + [null, 'stdClass'], + [new stdClass, null], + ]], + + ['strlen', [ + [null, null], + [new Cls, null], + [new Cls, 'Cls'], + [null, 'Cls'], + [null, 'stdClass'], + [new stdClass, null], + ]], + + [['Cls', 'staticMethod'], [ + [null, 'Cls'], + [new Cls, null], + [new Cls, 'Cls'], + [null, null], + [null, 'ClsChild'], + [null, 'ClsUnrelated'], + ]], + + [[new Cls, 'method'], [ + [null, 'Cls'], + [new Cls, 'Cls'], + [new ClsChild, 'Cls'], + [new ClsUnrelated, 'Cls'], + [new Cls, null], + [new Cls, 'ClsUnrelated'], + [new Cls, 'ClsChild'], + ]], + + [[new DLL, 'count'], [ + [new DLL, DLL::class], + [new SplStack, DLL::class], + [new ClsUnrelated, DLL::class], + [null, null], + [null, DLL::class], + [new DLL, null], + [new DLL, ClsUnrelated::class], + ]], +]; + +set_error_handler(function($errno, $errstr) { + echo "$errstr\n\n"; +}); + +foreach ($tests as list($fn, $bindings)) { + if (is_array($fn)) { + $r = new ReflectionMethod($fn[0], $fn[1]); + $c = $r->getClosure(is_object($fn[0]) ? $fn[0] : null); + $fnStr = is_object($fn[0]) ? "(new " . get_class($fn[0]) . ")->$fn[1]" : "$fn[0]::$fn[1]"; + } else { + $c = (new ReflectionFunction($fn))->getClosure(); + $fnStr = $fn; + } + + echo "$fnStr()\n" . str_repeat('-', strlen($fnStr) + 2), "\n\n"; + + foreach ($bindings as list($obj, $scope)) { + $objStr = $obj ? "new " . get_class($obj) : "null"; + $scopeStr = $scope ? "$scope::class" : "null"; + echo "bindTo($objStr, $scopeStr):\n"; + + $ret = $c->bindTo($obj, $scope); + if ($ret !== null) { + echo "Success!\n\n"; + } + } +} + +?> +--EXPECT-- +func() +------ + +bindTo(null, null): +Success! + +bindTo(new Cls, null): +Success! + +bindTo(new Cls, Cls::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(null, Cls::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(null, stdClass::class): +Cannot bind closure to scope of internal class stdClass + +bindTo(new stdClass, null): +Success! + +strlen() +-------- + +bindTo(null, null): +Success! + +bindTo(new Cls, null): +Success! + +bindTo(new Cls, Cls::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(null, Cls::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(null, stdClass::class): +Cannot bind closure to scope of internal class stdClass + +bindTo(new stdClass, null): +Success! + +Cls::staticMethod() +------------------- + +bindTo(null, Cls::class): +Success! + +bindTo(new Cls, null): +Cannot bind an instance to a static closure + +bindTo(new Cls, Cls::class): +Cannot bind an instance to a static closure + +bindTo(null, null): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(null, ClsChild::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(null, ClsUnrelated::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +(new Cls)->method() +------------------- + +bindTo(null, Cls::class): +Success! + +bindTo(new Cls, Cls::class): +Success! + +bindTo(new ClsChild, Cls::class): +Success! + +bindTo(new ClsUnrelated, Cls::class): +Success! + +bindTo(new Cls, null): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(new Cls, ClsUnrelated::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(new Cls, ClsChild::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +(new SplDoublyLinkedList)->count() +---------------------------------- + +bindTo(new SplDoublyLinkedList, SplDoublyLinkedList::class): +Success! + +bindTo(new SplStack, SplDoublyLinkedList::class): +Success! + +bindTo(new ClsUnrelated, SplDoublyLinkedList::class): +Cannot bind internal method SplDoublyLinkedList::count() to object of class ClsUnrelated + +bindTo(null, null): +Cannot unbind $this of internal method + +bindTo(null, SplDoublyLinkedList::class): +Cannot unbind $this of internal method + +bindTo(new SplDoublyLinkedList, null): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() + +bindTo(new SplDoublyLinkedList, ClsUnrelated::class): +Cannot rebind scope of closure created by ReflectionFunctionAbstract::getClosure() |