123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- --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],
- ]],
- [function() {}, [
- [null, null],
- [new Cls, null],
- [new Cls, 'Cls'],
- [null, 'Cls'],
- [null, 'stdClass'],
- [new stdClass, null],
- ]],
- ];
- 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;
- }
- if ($fn instanceof Closure) {
- $fnStr = "(function() {})";
- }
- 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 from function
- bindTo(null, Cls::class):
- Cannot rebind scope of closure created from function
- 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 from function
- bindTo(null, Cls::class):
- Cannot rebind scope of closure created from function
- 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 from method
- bindTo(null, ClsChild::class):
- Cannot rebind scope of closure created from method
- bindTo(null, ClsUnrelated::class):
- Cannot rebind scope of closure created from method
- (new Cls)->method()
- -------------------
- bindTo(null, Cls::class):
- Cannot unbind $this of method
- bindTo(new Cls, Cls::class):
- Success!
- bindTo(new ClsChild, Cls::class):
- Success!
- bindTo(new ClsUnrelated, Cls::class):
- Cannot bind method Cls::method() to object of class ClsUnrelated
- bindTo(new Cls, null):
- Cannot rebind scope of closure created from method
- bindTo(new Cls, ClsUnrelated::class):
- Cannot rebind scope of closure created from method
- bindTo(new Cls, ClsChild::class):
- Cannot rebind scope of closure created from method
- (new SplDoublyLinkedList)->count()
- ----------------------------------
- bindTo(new SplDoublyLinkedList, SplDoublyLinkedList::class):
- Success!
- bindTo(new SplStack, SplDoublyLinkedList::class):
- Success!
- bindTo(new ClsUnrelated, SplDoublyLinkedList::class):
- Cannot bind method SplDoublyLinkedList::count() to object of class ClsUnrelated
- bindTo(null, null):
- Cannot unbind $this of method
- bindTo(null, SplDoublyLinkedList::class):
- Cannot unbind $this of method
- bindTo(new SplDoublyLinkedList, null):
- Cannot rebind scope of closure created from method
- bindTo(new SplDoublyLinkedList, ClsUnrelated::class):
- Cannot rebind scope of closure created from method
- (function() {})()
- -----------------
- bindTo(null, null):
- Success!
- bindTo(new Cls, null):
- Success!
- bindTo(new Cls, Cls::class):
- Success!
- bindTo(null, Cls::class):
- Success!
- bindTo(null, stdClass::class):
- Cannot bind closure to scope of internal class stdClass
- bindTo(new stdClass, null):
- Success!
|