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