1--TEST--
2mysqli_stmt_bind_result() - playing with references
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifconnectfailure.inc');
7?>
8--FILE--
9<?php
10    require('table.inc');
11
12    $stmt = mysqli_stmt_init($link);
13    if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1"))
14        printf("[001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
15
16    if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1"))
17        printf("[001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
18
19
20    print "plain vanilla...\n";
21    unset($id); unset($label);
22    $id = $label = null;
23    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
24        printf("[002] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
25
26    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
27        printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
28
29    var_dump($id);
30    var_dump($label);
31
32
33    print "reference, one level...\n";
34    unset($id); unset($id_ref); unset($label); unset($label_ref);
35    $id = null;
36    $id_ref = &$id;
37    $label = null;
38    $label_ref = &$label;
39
40    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref, $label_ref)))
41        printf("[004] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
42
43    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
44        printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
45    var_dump($id_ref);
46    var_dump($id);
47    var_dump($label_ref);
48    var_dump($label);
49
50
51    print "reference, two levels...\n";
52    unset($id); unset($id_ref); unset($id_ref_ref); unset($label); unset($label_ref); unset($label_ref_ref);
53    $id = null;
54    $id_ref = &$id;
55    $id_ref_ref = &$id_ref;
56    $label = null;
57    $label_ref = &$label;
58    $label_ref_ref = &$label_ref;
59
60    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref_ref, $label_ref_ref)))
61        printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
62
63    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
64        printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
65    var_dump($id_ref_ref);
66    var_dump($id_ref);
67    var_dump($id);
68    var_dump($label_ref_ref);
69    var_dump($label_ref);
70    var_dump($label);
71
72    print "reference, \$GLOBALS...\n";
73    unset($id); unset($id_ref); unset($label); unset($label_ref);
74    $id = 100;
75    $id_ref = &$GLOBALS['id'];
76    $label = null;
77    $label_ref = &$GLOBALS['label'];
78
79    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref, $label_ref)))
80        printf("[008] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
81
82    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
83        printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
84    var_dump($id_ref);
85    var_dump($id);
86    var_dump($label_ref);
87    var_dump($label);
88
89    print "reference, same target...\n";
90    $id = null;
91    $label = &$id;
92
93    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
94        printf("[010] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
95
96    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
97        printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
98
99    var_dump($id);
100    var_dump($label);
101
102    print "reference, simple object...\n";
103    unset($obj);
104    $obj = new stdClass();
105    $obj->id = null;
106    $obj->label = null;
107
108    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $obj->id, $obj->label)))
109        printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
110
111    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
112        printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
113
114    var_dump($obj->id);
115    var_dump($obj->label);
116
117
118    print "reference, simple object w reference...\n";
119    unset($id); unset($label); unset($obj);
120    $obj = new stdClass();
121    $obj->id = null;
122    $obj->label = null;
123    $id = &$obj->id;
124    $label = &$obj->label;
125
126    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
127        printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
128
129    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
130        printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
131
132    var_dump($obj->id);
133    var_dump($obj->label);
134
135    print "reference, simple object w reference, change after bind...\n";
136    unset($id); unset($label); unset($obj);
137    $obj = new stdClass();
138    $obj->id = null;
139    $obj->label = null;
140    $id = &$obj->id;
141    $label = &$obj->label;
142
143    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
144        printf("[012] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
145
146    $label = &$obj->id;
147    $id = null;
148
149    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
150        printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
151
152    var_dump($obj->id);
153    var_dump($id);
154    var_dump($obj->label);
155    var_dump($label);
156
157    print "reference, one level, change after bind...\n";
158    unset($id); unset($label); unset($id_ref); unset($label_ref);
159    $id = null;
160    $id_ref = &$id;
161    $label = null;
162    $label_ref = &$label;
163
164    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id_ref, $label_ref)))
165        printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
166
167    $id_ref = 1;
168    $label_ref = 1;
169
170    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
171        printf("[015] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
172    var_dump($id_ref);
173    var_dump($id);
174    var_dump($label_ref);
175    var_dump($label);
176
177    print "reference, circle...\n";
178    unset($id); unset($label_a); unset($label_b);
179    $id = null;
180    $label_a = &$label_b;
181    $label_b = &$label_a;
182
183    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label_a)))
184        printf("[016] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
185    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
186        printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
187
188    var_dump($id);
189    var_dump($label_a);
190    var_dump($label_b);
191
192    print "reference, object, forward declaration...\n";
193    unset($bar); unset($id); unset($label_ref);
194    class foo {
195        public $foo;
196        public function __construct() {
197            $this->foo = &$this->bar;
198        }
199    }
200    class bar extends foo {
201        public $bar = null;
202    }
203    $bar = new bar();
204    $id = null;
205    $label_ref = &$bar->bar;
206
207    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label_ref)))
208        printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
209    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
210        printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
211
212    var_dump($id);
213    var_dump($bar);
214    var_dump($label_ref);
215
216    print "references, object, private...\n";
217    unset($bar); unset($id); unset($label);
218    class mega_bar extends bar {
219        private $id;
220        public $id_ref;
221        public function __construct() {
222            parent::__construct();
223            $this->id_ref = &$this->id;
224        }
225    }
226    $bar = new mega_bar();
227    $id = &$bar->id_ref;
228    $label = &$bar->foo;
229
230    if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
231        printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
232    if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_fetch($stmt) || mysqli_stmt_fetch($stmt))
233        printf("[021] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
234    var_dump($id);
235    var_dump($label);
236    var_dump($bar);
237
238    mysqli_stmt_close($stmt);
239    mysqli_close($link);
240
241    print "done!";
242?>
243--CLEAN--
244<?php
245    require_once("clean_table.inc");
246?>
247--EXPECTF--
248plain vanilla...
249int(1)
250string(1) "a"
251reference, one level...
252int(1)
253int(1)
254string(1) "a"
255string(1) "a"
256reference, two levels...
257int(1)
258int(1)
259int(1)
260string(1) "a"
261string(1) "a"
262string(1) "a"
263reference, $GLOBALS...
264int(1)
265int(1)
266string(1) "a"
267string(1) "a"
268reference, same target...
269string(1) "a"
270string(1) "a"
271reference, simple object...
272int(1)
273string(1) "a"
274reference, simple object w reference...
275int(1)
276string(1) "a"
277reference, simple object w reference, change after bind...
278int(1)
279int(1)
280string(1) "a"
281int(1)
282reference, one level, change after bind...
283int(1)
284int(1)
285string(1) "a"
286string(1) "a"
287reference, circle...
288int(1)
289string(1) "a"
290string(1) "a"
291reference, object, forward declaration...
292int(1)
293object(bar)#%d (2) {
294  ["bar"]=>
295  &string(1) "a"
296  ["foo"]=>
297  &string(1) "a"
298}
299string(1) "a"
300references, object, private...
301int(1)
302string(1) "a"
303object(mega_bar)#5 (4) {
304  [%s]=>
305  &int(1)
306  ["id_ref"]=>
307  &int(1)
308  ["bar"]=>
309  &string(1) "a"
310  ["foo"]=>
311  &string(1) "a"
312}
313done!
314