xref: /PHP-7.0/Zend/tests/closure_041.phpt (revision 4b821f0f)
1--TEST--
2Closure 041: Rebinding: preservation of previous scope when not given as arg unless impossible
3--FILE--
4<?php
5
6/* It's impossible to preserve the previous scope when doing so would break
7 * the invariants that, for non-static closures, having a scope is equivalent
8 * to having a bound instance. */
9
10$staticUnscoped = static function () {
11	echo "scoped to A: "; var_dump(isset(A::$priv));
12	echo "bound: ", isset($this)?get_class($this):"no";
13};
14
15$nonstaticUnscoped = function () {
16	echo "scoped to A: "; var_dump(isset(A::$priv));
17	echo "bound: ", isset($this)?get_class($this):"no";
18};
19
20class A {
21	private static $priv = 7;
22	function getClosure() {
23		return function () {
24			echo "scoped to A: "; var_dump(isset(A::$priv));
25			echo "bound: ", isset($this)?get_class($this):"no";
26		};
27	}
28	function getStaticClosure() {
29		return static function () {
30			echo "scoped to A: "; var_dump(isset(A::$priv));
31			echo "bound: ", isset($this)?get_class($this):"no";
32		};
33	}
34}
35class B extends A {}
36
37$a = new A();
38$staticScoped = $a->getStaticClosure();
39$nonstaticScoped = $a->getClosure();
40
41echo "Before binding", "\n";
42$staticUnscoped(); echo "\n";
43$nonstaticUnscoped(); echo "\n";
44$staticScoped(); echo "\n";
45$nonstaticScoped(); echo "\n";
46
47echo "After binding, no instance", "\n";
48$d = $staticUnscoped->bindTo(null); $d(); echo "\n";
49$d = $nonstaticUnscoped->bindTo(null); $d(); echo "\n";
50$d = $staticScoped->bindTo(null); $d(); echo "\n";
51$d = $nonstaticScoped->bindTo(null); $d(); echo "\n";
52// $d is still non-static
53$d->bindTo($d);
54
55echo "After binding, with same-class instance for the bound ones", "\n";
56$d = $staticUnscoped->bindTo(new A);
57$d = $nonstaticUnscoped->bindTo(new A); $d(); echo " (should be scoped to dummy class)\n";
58$d = $staticScoped->bindTo(new A);
59$d = $nonstaticScoped->bindTo(new A); $d(); echo "\n";
60
61echo "After binding, with different instance for the bound ones", "\n";
62$d = $nonstaticUnscoped->bindTo(new B); $d(); echo " (should be scoped to dummy class)\n";
63$d = $nonstaticScoped->bindTo(new B); $d(); echo "\n";
64
65echo "Done.\n";
66
67--EXPECTF--
68Before binding
69scoped to A: bool(false)
70bound: no
71scoped to A: bool(false)
72bound: no
73scoped to A: bool(true)
74bound: no
75scoped to A: bool(true)
76bound: A
77After binding, no instance
78scoped to A: bool(false)
79bound: no
80scoped to A: bool(false)
81bound: no
82scoped to A: bool(true)
83bound: no
84scoped to A: bool(true)
85bound: no
86After binding, with same-class instance for the bound ones
87
88Warning: Cannot bind an instance to a static closure in %s on line %d
89scoped to A: bool(false)
90bound: A (should be scoped to dummy class)
91
92Warning: Cannot bind an instance to a static closure in %s on line %d
93scoped to A: bool(true)
94bound: A
95After binding, with different instance for the bound ones
96scoped to A: bool(false)
97bound: B (should be scoped to dummy class)
98scoped to A: bool(true)
99bound: B
100Done.
101