1--TEST--
2mysqli_stmt_bind_param()
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifconnectfailure.inc');
7?>
8--FILE--
9<?php
10    /*
11    The way we test the INSERT and data types overlaps with
12    the mysqli_stmt_bind_result test in large parts. There is only
13    one difference. This test uses mysqli_query()/mysqli_fetch_assoc() to
14    fetch the inserted values. This way we test
15    mysqli_query()/mysqli_fetch_assoc() for all possible data types
16    in this file and we test mysqli_stmt_bind_result() in the other
17    test -- therefore the "duplicate" makes some sense to me.
18    */
19    require_once("connect.inc");
20
21    require('table.inc');
22
23    $stmt = mysqli_stmt_init($link);
24    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
25        printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
26
27    $id = null;
28    $label = null;
29
30    /*
31    libmysql gives a less descriptive error message but mysqlnd,
32    we did not unify the error messages but ignore this slight difference silently
33    */
34    try {
35        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, " ", $tmp)))
36            printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
37    } catch (\ArgumentCountError $e) {
38        echo $e->getMessage() . \PHP_EOL;
39    }
40
41    try {
42        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "", $id, $label)))
43            printf("[003a] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
44    } catch (\ValueError $e) {
45        echo $e->getMessage() . \PHP_EOL;
46    }
47
48    /* TODO: somehwhat undocumented syntax! */
49    $param = array($id);
50    try {
51        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param)))
52         printf("[003b] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
53    } catch (\ArgumentCountError $e) {
54        echo $e->getMessage() . \PHP_EOL;
55    }
56
57    $param = array($id, $label, $id);
58    try {
59        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, " ", $tmp)))
60            printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
61    } catch (\ArgumentCountError $e) {
62        echo $e->getMessage() . \PHP_EOL;
63    }
64    try {
65        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param)))
66            printf("[003c] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
67    } catch (\ArgumentCountError $e) {
68        echo $e->getMessage() . \PHP_EOL;
69    }
70
71    try {
72        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id)))
73            printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
74    } catch (\ArgumentCountError $e) {
75        echo $e->getMessage() . \PHP_EOL;
76    }
77
78    try {
79        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id, $label)))
80            printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
81    } catch (\ArgumentCountError $e) {
82        echo $e->getMessage() . \PHP_EOL;
83    }
84
85    try {
86        mysqli_stmt_bind_param($stmt, "aa", $id, $label);
87    } catch (ValueError $e) {
88        echo $e->getMessage() . \PHP_EOL;
89    }
90
91    try {
92        mysqli_stmt_bind_param($stmt, "ia", $id, $label);
93    } catch (ValueError $e) {
94        echo $e->getMessage() . \PHP_EOL;
95    }
96
97    try {
98        if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
99            printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
100    } catch (\ArgumentCountError $e) {
101        echo $e->getMessage() . \PHP_EOL;
102    }
103
104    if (function_exists("memory_get_usage")) {
105        $mem = memory_get_usage();
106        for ($i = 0; $i < 20000; $i++) {
107            if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
108                printf("[008][$i] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
109        }
110        if (($tmp = (memory_get_usage() - $mem)) > 600)
111            printf("[009] Function seems to be leaking, because it used %d bytes. During tests it used only 92 bytes.", $tmp);
112    }
113
114    $id = 100;
115    $label = "z";
116    if (!mysqli_stmt_execute($stmt))
117        printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
118
119    mysqli_stmt_close($stmt);
120
121    if (!($res = mysqli_query($link, "SELECT id, label FROM test WHERE id = " . $id)))
122        printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
123    $row = mysqli_fetch_assoc($res);
124    if (($row['id'] != $id) || ($row['label'] != $label))
125        printf("[012] Expecting '%s'/%s', got '%s'/%s'!\n", $id, $label, $row['id'], $row['label']);
126    mysqli_free_result($res);
127
128    function func_mysqli_stmt_bind_datatype($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $alternative = null) {
129
130        if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
131            printf("[%03d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link));
132            return false;
133        }
134
135        if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) {
136            // don't bail - it might be that the server does not support the data type
137            return false;
138        }
139
140        if (!$stmt = mysqli_stmt_init($link)) {
141            printf("[%03d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
142            return false;
143        }
144
145        if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUE (?, ?)")) {
146            printf("[%03d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
147            return false;
148        }
149
150        $id = 1;
151        if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) {
152            printf("[%03d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
153            return false;
154        }
155
156        if (!mysqli_stmt_execute($stmt)) {
157            printf("[%03d] [%d] %s\n", $offset + 4, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
158            return false;
159        }
160        mysqli_stmt_close($stmt);
161
162        if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
163            printf("[%03d] [%d] %s\n", $offset + 5, mysqli_errno($link), mysqli_error($link));
164            return false;
165        }
166
167        if (!$row = mysqli_fetch_assoc($res)) {
168            printf("[%03d] [%d] %s\n", $offset + 5, mysqli_errno($link), mysqli_error($link));
169            return false;
170        }
171
172        if ($alternative) {
173            if (($row['id'] != $id) || (($row['label'] != $bind_value) && ($row['label'] != $alternative))) {
174                printf("[%03d] Testing '%s', '%s': expecting '%s'/'%s' (%s), got '%s'/'%s'\n",
175                    $offset + 6, $bind_type, $sql_type,
176                    $id, $bind_value, gettype($bind_value), $row['id'], $row['label']);
177                return false;
178            }
179        } else {
180            if (($row['id'] != $id) || ($row['label'] != $bind_value)) {
181                printf("[%03d] Testing '%s', '%s': expecting '%s'/'%s', got '%s'/'%s'\n",
182                    $offset + 6, $bind_type, $sql_type,
183                    $id, $bind_value, $row['id'], $row['label']);
184                return false;
185            }
186        }
187
188        mysqli_free_result($res);
189        return true;
190    }
191
192    function func_mysqli_stmt_bind_make_string($len) {
193
194        $ret = '';
195        for ($i = 0; $i < $len; $i++)
196            $ret .= chr(mt_rand(65, 90));
197
198        return $ret;
199    }
200
201    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT", -11, 20);
202    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT", NULL, 30);
203    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT UNSIGNED", 1, 40);
204    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT UNSIGNED", NULL, 50);
205
206    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOL", 1, 60);
207    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOL", NULL, 70);
208    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOLEAN", 0, 80);
209    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOLEAN", NULL, 90);
210
211    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", -32768, 100);
212    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", 32767, 110);
213    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", NULL, 120);
214    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 130);
215    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 140);
216
217    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", -8388608, 150);
218    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", 8388607, 160);
219    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", NULL, 170);
220    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT UNSIGNED", 16777215, 180);
221    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT UNSIGNED", NULL, 190);
222
223    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", -2147483648, 200);
224    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", 2147483647, 210);
225    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", NULL, 220);
226    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, PHP_INT_MAX) : 1, 230);
227    func_mysqli_stmt_bind_datatype($link, $engine, "d", "INTEGER UNSIGNED", 4294967295, 240);
228    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER UNSIGNED", NULL, 250);
229
230    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 260);
231    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", NULL, 270);
232    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", PHP_INT_MAX, 280);
233    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT UNSIGNED", NULL, 290);
234
235    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BIGINT", "-9223372036854775808", 900);
236    // ?? func_mysqli_stmt_bind_datatype($link, $engine, "d", "BIGINT", -9223372036854775808, 910);
237    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 920);
238
239/*
240    ??
241    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 300);
242    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 320);
243    */
244    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", NULL, 310);
245    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 330);
246    if (2147483647 == PHP_INT_MAX) {
247        func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", PHP_INT_MAX, 930, '2.14748e+09');
248        func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -1 * PHP_INT_MAX + 1, 940, '-2.14748e+09');
249    }
250    func_mysqli_stmt_bind_datatype($link, $engine, "s", "FLOAT", "-9223372036854775808", 300, '-9.22337e+18');
251    func_mysqli_stmt_bind_datatype($link, $engine, "s", "FLOAT UNSIGNED", "18446744073709551615", 320, '1.84467e+19');
252    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -10.01, 950);
253    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", 10.01, 960);
254
255    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", NULL, 350);
256    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 370);
257    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 340);
258    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99, 360);
259
260    /*
261    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 340);
262    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99, 360);
263        */
264    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", -99999999.99, 380);
265    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", NULL, 390);
266    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", 99999999.99, 400);
267    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", NULL, 410);
268
269    // don't care about date() strict TZ warnings...
270    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE", @date('Y-m-d'), 420);
271    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 430);
272    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE", NULL, 440);
273
274    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 450);
275    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 460);
276    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME", NULL, 470);
277
278    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 480);
279
280    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", @date('H:i:s'), 490);
281    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 500);
282    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", NULL, 510);
283
284    func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR", @date('Y'), 520);
285    func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR NOT NULL", @date('Y'), 530);
286    func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR", NULL, 540);
287
288    $string255 = func_mysqli_stmt_bind_make_string(255);
289    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1)", "a", 550);
290    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(255)", $string255, 560);
291    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1) NOT NULL", "a", 570);
292    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1)", NULL, 580);
293
294    $string65k = func_mysqli_stmt_bind_make_string(65535);
295    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1)", "a", 590);
296    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(255)", $string255, 600);
297    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(65635)", $string65k, 610);
298    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 620);
299    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1)", NULL, 630);
300
301    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", "a", 640);
302    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", chr(0), 650);
303    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1) NOT NULL", "b", 660);
304    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", NULL, 670);
305
306    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", "a", 680);
307    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", chr(0), 690);
308    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 700);
309    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", NULL, 710);
310
311    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", "a", 720);
312    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", chr(0), 730);
313    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB NOT NULL", "b", 740);
314    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", NULL, 750);
315
316    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT", "a", 760);
317    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT NOT NULL", "a", 770);
318    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT", NULL, 780);
319
320    // Note: you cannot insert any blob values this way. But you can check the API at least partly this way
321    // Extra BLOB tests are in mysqli_stmt_send_long()
322    func_mysqli_stmt_bind_datatype($link, $engine, "b", "BLOB", "", 790);
323    func_mysqli_stmt_bind_datatype($link, $engine, "b", "TEXT", "", 800);
324    func_mysqli_stmt_bind_datatype($link, $engine, "b", "MEDIUMBLOB", "", 810);
325    func_mysqli_stmt_bind_datatype($link, $engine, "b", "MEDIUMTEXT", "", 820);
326    func_mysqli_stmt_bind_datatype($link, $engine, "b", "LONGBLOB", "", 830);
327    func_mysqli_stmt_bind_datatype($link, $engine, "b", "LONGTEXT", "", 840);
328
329    func_mysqli_stmt_bind_datatype($link, $engine, "s", "ENUM('a', 'b')", "a", 850);
330    func_mysqli_stmt_bind_datatype($link, $engine, "s", "ENUM('a', 'b')", NULL, 860);
331    func_mysqli_stmt_bind_datatype($link, $engine, "s", "SET('a', 'b')", "a", 870);
332    func_mysqli_stmt_bind_datatype($link, $engine, "s", "SET('a', 'b')", NULL, 880);
333
334    if (mysqli_get_server_version($link) >= 50600)
335        func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", "13:27:34.123456", 890, "13:27:34");
336
337    $stmt = mysqli_stmt_init($link);
338    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
339        printf("[2000] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
340
341    $id = null;
342    $label = null;
343    if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
344        printf("[2001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
345
346    mysqli_stmt_execute($stmt);
347
348    if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
349        printf("[2002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
350
351    mysqli_stmt_close($stmt);
352    include("table.inc");
353
354    if (!$stmt = mysqli_stmt_init($link))
355        printf("[2003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
356
357    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
358        printf("[2004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
359
360    $id = $label = null;
361    if (true !== ($tmp = $stmt->bind_param('is', $id, $label)))
362        printf("[2005] Expecting boolean/true got %s/%s, [%d] %s\n",
363            gettype($tmp), $tmp,
364            $stmt->errno, $stmt->error);
365
366    $id = 100; $label = 'z';
367    if (!$stmt->execute())
368        printf("[2006] [%d] %s\n", $stmt->errno, $stmt->error);
369
370    if (!$res = mysqli_query($link, "SELECT id, label FROM test WHERE id = 100"))
371        printf("[2007] Expecting record 100/z, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
372
373    if (!$row = mysqli_fetch_assoc($res))
374        printf("[2008] Expecting row, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
375
376    if ($row['id'] != 100  || $row['label'] != 'z') {
377        printf("[2009] Row seems wrong, dumping record\n");
378        var_dump($row);
379    }
380    mysqli_free_result($res);
381
382    $value_list = array(array('id' => 101, 'label' => 'a'), array('id' => 102, 'label' => 'b'));
383    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
384        printf("[2010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
385
386        foreach ($value_list as $k => $values) {
387        if (!mysqli_stmt_bind_param($stmt, 'is', $values['id'], $values['label'])) {
388            printf("[2011] bind_param() failed for id = %d, [%d] %s\n",
389                $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
390            continue;
391        }
392        if (!$stmt->execute())
393            printf("[2012] [%d] execute() failed for id = %d, [%d] %s\n",
394                $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
395
396        if (!$res = mysqli_query($link, sprintf("SELECT label FROM test WHERE id = %d", $values['id'])))
397            printf("[2013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
398        if (!$row = mysqli_fetch_assoc($res))
399            printf("[2014] Cannot find row id = %d\n", $values['id']);
400        else if (isset($row['label']) && ($values['label'] != $row['label']))
401            printf("[2015] Expecting label = %s, got label = %s\n", $values['label'], $row['label']);
402
403        mysqli_free_result($res);
404    }
405
406    mysqli_stmt_close($stmt);
407    mysqli_close($link);
408
409    print "done!";
410?>
411--CLEAN--
412<?php
413    require_once("clean_table.inc");
414?>
415--EXPECT--
416The number of variables must match the number of parameters in the prepared statement
417mysqli_stmt_bind_param(): Argument #2 ($types) cannot be empty
418The number of elements in the type definition string must match the number of bind variables
419The number of variables must match the number of parameters in the prepared statement
420The number of elements in the type definition string must match the number of bind variables
421The number of variables must match the number of parameters in the prepared statement
422The number of elements in the type definition string must match the number of bind variables
423mysqli_stmt_bind_param(): Argument #2 ($types) must only contain the "b", "d", "i", "s" type specifiers
424mysqli_stmt_bind_param(): Argument #2 ($types) must only contain the "b", "d", "i", "s" type specifiers
425done!
426