1--TEST--
2mysqli_stmt_bind_param used with call_user_func_array() (see also bug #43568)
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifemb.inc');
7require_once('skipifconnectfailure.inc');
8?>
9--FILE--
10<?php
11	require('connect.inc');
12	require('table.inc');
13
14	if (!$stmt = mysqli_stmt_init($link))
15		printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
16
17	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
18		printf("[002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
19
20	$id = 1;
21	if (!mysqli_stmt_bind_param($stmt, 'i', $id) ||
22		!mysqli_stmt_execute($stmt))
23		printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
24
25	$id = $label = null;
26	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
27		(true !== mysqli_stmt_fetch($stmt)))
28		printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
29
30	print "Regular, procedural, using variables\n";
31	var_dump($id);
32	var_dump($label);
33
34	mysqli_stmt_close($stmt);
35	if (!$stmt = mysqli_stmt_init($link))
36		printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
37
38	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
39		printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
40
41	$types = 'i';
42	$id = 1;
43	$params = array(
44		0 => &$stmt,
45		1 => &$types,
46		2 => &$id
47	);
48	if (!call_user_func_array('mysqli_stmt_bind_param', $params))
49		printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
50
51	if (!mysqli_stmt_execute($stmt))
52		printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
53
54	$id = $label = null;
55	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
56		(true !== mysqli_stmt_fetch($stmt)))
57		printf("[009] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
58
59	print "Call user func, procedural, using references for everything\n";
60	var_dump($id);
61	var_dump($label);
62
63	mysqli_stmt_close($stmt);
64	if (!$stmt = mysqli_stmt_init($link))
65		printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
66
67	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
68		printf("[011] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
69
70	$types = 'i';
71	$id = 1;
72	$params = array(
73		0 => &$types,
74		1 => &$id
75	);
76	if (!call_user_func_array(array($stmt, 'bind_param'), $params))
77		printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
78
79	if (!mysqli_stmt_execute($stmt))
80		printf("[013] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
81
82	$id = $label = null;
83	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
84		(true !== mysqli_stmt_fetch($stmt)))
85		printf("[014] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
86
87	print "Call user func, object oriented, using references for everything\n";
88	var_dump($id);
89	var_dump($label);
90
91	mysqli_stmt_close($stmt);
92	if (!$stmt = mysqli_stmt_init($link))
93		printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
94
95	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
96		printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
97
98	$types = 'i';
99	$id = 1;
100	$params = array(
101		0 => $types,
102		1 => &$id
103	);
104	if (!call_user_func_array(array($stmt, 'bind_param'), $params))
105		printf("[017] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
106
107	if (!mysqli_stmt_execute($stmt))
108		printf("[018] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
109
110	$id = $label = null;
111	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
112		(true !== mysqli_stmt_fetch($stmt)))
113		printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
114
115	print "Call user func, object oriented, using variable for types. using references for bound parameter\n";
116	var_dump($id);
117	var_dump($label);
118
119	mysqli_stmt_close($stmt);
120	if (!$stmt = mysqli_stmt_init($link))
121		printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
122
123	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
124		printf("[021] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
125
126	$id = 1;
127	$params = array(
128		0 => 'i',
129		1 => &$id
130	);
131	if (!call_user_func_array(array($stmt, 'bind_param'), $params))
132		printf("[022] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
133
134	if (!mysqli_stmt_execute($stmt))
135		printf("[023] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
136
137	$id = $label = null;
138	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
139		(true !== mysqli_stmt_fetch($stmt)))
140		printf("[024] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
141
142	print "Call user func, object oriented, using constant for types. using references for bound parameter\n";
143	var_dump($id);
144	var_dump($label);
145
146	mysqli_stmt_close($stmt);
147	if (!$stmt = mysqli_stmt_init($link))
148		printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
149
150	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
151		printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
152
153	$types = 'i';
154	$id = 1;
155	$params = array(
156		0 => &$stmt,
157		1 => $types,
158		2 => &$id
159	);
160	if (!call_user_func_array('mysqli_stmt_bind_param', $params))
161		printf("[027] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
162
163	if (!mysqli_stmt_execute($stmt))
164		printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
165
166	$id = $label = null;
167	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
168		(true !== mysqli_stmt_fetch($stmt)))
169		printf("[029] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
170
171	print "Call user func, procedural, using references for everything but using variable for types\n";
172	var_dump($id);
173	var_dump($label);
174
175	mysqli_stmt_close($stmt);
176	if (!$stmt = mysqli_stmt_init($link))
177		printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
178
179	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
180		printf("[026] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
181
182	$types = 'i';
183	$id = 1;
184	$params = array(
185		0 => $stmt,
186		1 => $types,
187		2 => &$id
188	);
189	if (!call_user_func_array('mysqli_stmt_bind_param', $params))
190		printf("[027] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
191
192	if (!mysqli_stmt_execute($stmt))
193		printf("[028] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
194
195	$id = $label = null;
196	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
197		(true !== mysqli_stmt_fetch($stmt)))
198		printf("[029] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
199
200	print "Call user func, procedural, using references for bound parameter, using variables for resource and types\n";
201	var_dump($id);
202	var_dump($label);
203
204	mysqli_stmt_close($stmt);
205	if (!$stmt = mysqli_stmt_init($link))
206		printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
207
208	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
209		printf("[031] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
210
211	$types = 'i';
212	$id = 1;
213	$params = array(
214		0 => $stmt,
215		1 => $types,
216		2 => &$id
217	);
218	if (!call_user_func_array('mysqli_stmt_bind_param', $params))
219		printf("[032] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
220
221	if (!mysqli_stmt_execute($stmt))
222		printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
223
224	$id = $label = null;
225	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
226		(true !== mysqli_stmt_fetch($stmt)))
227		printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
228
229	print "Call user func, procedural, using references for bound parameter, using variables for resource and types\n";
230	var_dump($id);
231	var_dump($label);
232
233	mysqli_stmt_close($stmt);
234	if (!$stmt = mysqli_stmt_init($link))
235		printf("[035] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
236
237	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
238		printf("[036] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
239
240	$id = 1;
241	$params = array(
242		0 => $stmt,
243		1 => 'i',
244		2 => &$id
245	);
246	if (!call_user_func_array('mysqli_stmt_bind_param', $params))
247		printf("[037] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
248
249	if (!mysqli_stmt_execute($stmt))
250		printf("[038] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
251
252	$id = $label = null;
253	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
254		(true !== mysqli_stmt_fetch($stmt)))
255		printf("[039] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
256
257	print "Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types\n";
258	var_dump($id);
259	var_dump($label);
260
261	mysqli_stmt_close($stmt);
262	if (!$stmt = mysqli_stmt_init($link))
263		printf("[040] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
264
265	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
266		printf("[041] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
267
268	$id = 1;
269	if (!call_user_func_array('mysqli_stmt_bind_param', array($stmt, 'i', &$id)))
270		printf("[042] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
271
272	if (!mysqli_stmt_execute($stmt))
273		printf("[043] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
274
275	$id = $label = null;
276	if (!mysqli_stmt_bind_result($stmt, $id, $label) ||
277		(true !== mysqli_stmt_fetch($stmt)))
278		printf("[044] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
279
280	print "Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types, array\n";
281	var_dump($id);
282	var_dump($label);
283
284	//
285	// Any of those shall fail - see also bugs.php.net/43568
286	//
287	mysqli_stmt_close($stmt);
288	if (!$stmt = mysqli_stmt_init($link))
289		printf("[045] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
290
291	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
292		printf("[046] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
293
294	$id = 1;
295	$params = array(
296		0 => 'i',
297		1 => &$id
298	);
299	if (!call_user_func_array(array($stmt, 'bind_param'), $params))
300		printf("[047] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
301
302	if (!mysqli_stmt_execute($stmt))
303		printf("[048] [%d] (Message might vary with MySQL Server version, e.g. No data supplied for parameters in prepared statement)\n", mysqli_stmt_errno($stmt));
304
305	mysqli_stmt_close($stmt);
306	if (!$stmt = mysqli_stmt_init($link))
307		printf("[049] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
308
309	if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test WHERE id = ?'))
310		printf("[050] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
311
312	$types = 'i';
313	$id = 1;
314	$params = array(
315		0 => $stmt,
316		1 => 'i',
317		2 => &$id
318	);
319	if (!call_user_func_array('mysqli_stmt_bind_param', $params))
320		printf("[051] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
321
322	if (!mysqli_stmt_execute($stmt))
323		printf("[052] [%d] (Message might vary with MySQL Server version, e.g. No data supplied for parameters in prepared statement)\n", mysqli_stmt_errno($stmt));
324
325	print "done!";
326?>
327--CLEAN--
328<?php
329	require_once("clean_table.inc");
330?>
331--EXPECT--
332Regular, procedural, using variables
333int(1)
334string(1) "a"
335Call user func, procedural, using references for everything
336int(1)
337string(1) "a"
338Call user func, object oriented, using references for everything
339int(1)
340string(1) "a"
341Call user func, object oriented, using variable for types. using references for bound parameter
342int(1)
343string(1) "a"
344Call user func, object oriented, using constant for types. using references for bound parameter
345int(1)
346string(1) "a"
347Call user func, procedural, using references for everything but using variable for types
348int(1)
349string(1) "a"
350Call user func, procedural, using references for bound parameter, using variables for resource and types
351int(1)
352string(1) "a"
353Call user func, procedural, using references for bound parameter, using variables for resource and types
354int(1)
355string(1) "a"
356Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types
357int(1)
358string(1) "a"
359Call user func, procedural, using references for bound parameter, using variable for resource, using constant for types, array
360int(1)
361string(1) "a"
362done!
363