xref: /PHP-8.4/tests/lang/bug20175.phpt (revision 462da6e0)
1--TEST--
2Bug #20175 (Static vars can't store ref to new instance)
3--INI--
4error_reporting=E_ALL
5--FILE--
6<?php
7print zend_version()."\n";
8
9/* Part 1:
10 * Storing the result of a function in a static variable.
11 * foo_global() increments global variable $foo_count whenever it is executed.
12 * When foo_static() is called it checks for the static variable $foo_value
13 * being initialized. In case initialisation is necessary foo_global() will be
14 * called. Since that must happen only once the return value should be equal.
15 */
16$foo_count = 0;
17
18function foo_global() {
19    global $foo_count;
20    echo "foo_global()\n";
21    return 'foo:' . ++$foo_count;
22}
23
24function foo_static() {
25    static $foo_value;
26    echo "foo_static()\n";
27    if (!isset($foo_value)) {
28        $foo_value = foo_global();
29    }
30    return $foo_value;
31}
32
33/* Part 2:
34 * Storing a reference to the result of a function in a static variable.
35 * Same as Part 1 but:
36 * The return statement transports a copy of the value to return. In other
37 * words the return value of bar_global() is a temporary variable only valid
38 * after the function call bar_global() is done in current local scope.
39 */
40$bar_count = 0;
41
42function bar_global() {
43    global $bar_count;
44    echo "bar_global()\n";
45    return 'bar:' . ++$bar_count;
46}
47
48function bar_static() {
49    static $bar_value;
50    echo "bar_static()\n";
51    if (!isset($bar_value)) {
52        $bar_value = &bar_global();
53    }
54    return $bar_value;
55}
56
57/* Part 3: TO BE DISCUSSED
58 *
59 * Storing a reference to the result of a function in a static variable.
60 * Same as Part 2 but wow_global() returns a reference so $wow_value
61 * should store a reference to $wow_global. Therefore $wow_value is already
62 * initialized in second call to wow_static() and hence shouldn't call
63 * wow_global() again.
64 */ /*
65$wow_count = 0;
66$wow_name = '';
67
68function &wow_global() {
69    global $wow_count, $wow_name;
70    echo "wow_global()\n";
71    $wow_name = 'wow:' . ++$wow_count;
72    return $wow_name;
73}
74
75function wow_static() {
76    static $wow_value;
77    echo "wow_static()\n";
78    if (!isset($wow_value)) {
79        $wow_value = &wow_global();
80    }
81    return $wow_value;
82}*/
83
84/* Part 4:
85 * Storing a reference to a new instance (that's where the name of the  test
86 * comes from). First there is the global counter $oop_global again which
87 * counts the calls to the constructor of oop_class and hence counts the
88 * creation of oop_class instances.
89 * The class oop_test uses a static reference to a oop_class instance.
90 * When another oop_test instance is created it must reuse the statically
91 * stored reference oop_value. This way oop_class gets some singleton behavior
92 * since it will be created only once for all instances of oop_test.
93 */
94$oop_global = 0;
95class oop_class {
96    var $oop_name;
97
98    function __construct() {
99        global $oop_global;
100        echo "oop_class()\n";
101        $this->oop_name = 'oop:' . ++$oop_global;
102    }
103}
104
105class oop_test {
106    static $oop_value;
107
108    function __construct() {
109        echo "oop_test()\n";
110    }
111
112    function oop_static() {
113        echo "oop_static()\n";
114        if (!isset(self::$oop_value)) {
115            self::$oop_value = new oop_class;
116        }
117        echo self::$oop_value->oop_name;
118    }
119}
120
121print foo_static()."\n";
122print foo_static()."\n";
123print bar_static()."\n";
124print bar_static()."\n";
125//print wow_static()."\n";
126//print wow_static()."\n";
127echo "wow_static()
128wow_global()
129wow:1
130wow_static()
131wow:1
132";
133$oop_tester = new oop_test;
134print $oop_tester->oop_static()."\n";
135print $oop_tester->oop_static()."\n";
136$oop_tester = new oop_test; // repeated.
137print $oop_tester->oop_static()."\n";
138?>
139--EXPECTF--
140%s
141foo_static()
142foo_global()
143foo:1
144foo_static()
145foo:1
146bar_static()
147bar_global()
148
149Notice: Only variables should be assigned by reference in %sbug20175.php on line 47
150bar:1
151bar_static()
152bar:1
153wow_static()
154wow_global()
155wow:1
156wow_static()
157wow:1
158oop_test()
159oop_static()
160oop_class()
161oop:1
162oop_static()
163oop:1
164oop_test()
165oop_static()
166oop:1
167