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