1--TEST-- 2mysqli_stmt_bind_result() 3--EXTENSIONS-- 4mysqli 5--SKIPIF-- 6<?php 7require_once('skipifconnectfailure.inc'); 8?> 9--FILE-- 10<?php 11 require_once("connect.inc"); 12 require('table.inc'); 13 14 $stmt = mysqli_stmt_init($link); 15 if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) 16 printf("[002a] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 17 18 mysqli_stmt_close($stmt); 19 $stmt = mysqli_stmt_init($link); 20 21 $id = null; 22 $label = null; 23 $foo = null; 24 25 try { 26 mysqli_stmt_bind_result($stmt, $id); 27 } catch (Error $exception) { 28 echo $exception->getMessage() . "\n"; 29 } 30 31 if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) 32 printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 33 34 try { 35 mysqli_stmt_bind_result($stmt, $id); 36 } catch (\ArgumentCountError $e) { 37 echo $e->getMessage() . PHP_EOL; 38 } 39 40 if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) 41 printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); 42 43 try { 44 mysqli_stmt_bind_result($stmt, $id, $label, $foo); 45 } catch (\ArgumentCountError $e) { 46 echo $e->getMessage() . PHP_EOL; 47 } 48 49 if (!mysqli_stmt_execute($stmt)) 50 printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 51 52 while (mysqli_stmt_fetch($stmt)) { 53 var_dump($id); 54 var_dump($label); 55 } 56 mysqli_stmt_close($stmt); 57 58 59 function func_mysqli_stmt_bind_result($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $type_hint = null) { 60 61 if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { 62 printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); 63 return false; 64 } 65 66 if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { 67 // don't bail - column type might not be supported by the server, ignore this 68 return false; 69 } 70 71 if (!$stmt = mysqli_stmt_init($link)) { 72 printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); 73 return false; 74 } 75 76 if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) { 77 printf("[%04d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 78 return false; 79 } 80 81 $id = null; 82 if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { 83 printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 84 mysqli_stmt_close($stmt); 85 return false; 86 } 87 88 for ($id = 1; $id < 4; $id++) { 89 if (!mysqli_stmt_execute($stmt)) { 90 printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 91 mysqli_stmt_close($stmt); 92 return false; 93 } 94 } 95 mysqli_stmt_close($stmt); 96 97 $stmt = mysqli_stmt_init($link); 98 99 if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { 100 printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 101 mysqli_stmt_close($stmt); 102 return false; 103 } 104 105 if (!mysqli_stmt_execute($stmt)) { 106 printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 107 mysqli_stmt_close($stmt); 108 return false; 109 } 110 111 $result = mysqli_stmt_result_metadata($stmt); 112 113 $bind_res = null; 114 if (!mysqli_stmt_bind_result($stmt, $id, $bind_res)) { 115 printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 116 mysqli_stmt_close($stmt); 117 return false; 118 } 119 $num = 0; 120 $fields = mysqli_fetch_fields($result); 121 122 while (mysqli_stmt_fetch($stmt)) { 123 if (!gettype($bind_res)=="unicode") { 124 if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { 125 printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", 126 $offset + 10, $num, 127 gettype($bind_value), $bind_value, $type_hint, 128 gettype($bind_res), $bind_res); 129 mysqli_stmt_close($stmt); 130 return false; 131 } 132 } 133 $num++; 134 } 135 136 if ($num != 3) { 137 printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", 138 $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); 139 mysqli_stmt_close($stmt); 140 return false; 141 } 142 143 mysqli_stmt_close($stmt); 144 return true; 145 } 146 147 148 function func_mysqli_stmt_bind_make_string($len) { 149 150 $ret = ''; 151 for ($i = 0; $i < $len; $i++) 152 $ret .= chr(mt_rand(65, 90)); 153 154 return $ret; 155 } 156 157 func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT", -11, 20); 158 func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT", NULL, 40); 159 func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT UNSIGNED", 1, 60); 160 func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT UNSIGNED", NULL, 80); 161 162 func_mysqli_stmt_bind_result($link, $engine, "i", "BOOL", 1, 100); 163 func_mysqli_stmt_bind_result($link, $engine, "i", "BOOL", NULL, 120); 164 func_mysqli_stmt_bind_result($link, $engine, "i", "BOOLEAN", 0, 140); 165 func_mysqli_stmt_bind_result($link, $engine, "i", "BOOLEAN", NULL, 160); 166 167 func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", -32768, 180); 168 func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", 32767, 200); 169 func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", NULL, 220); 170 func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 240); 171 func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 260); 172 173 func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", -8388608, 280, "integer"); 174 func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", 8388607, 300, "integer"); 175 func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", NULL, 320); 176 func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT UNSIGNED", 16777215, 340, "integer"); 177 func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT UNSIGNED", NULL, 360); 178 179 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? max(-1 * PHP_INT_MAX + 1, -2147483648) : 1, 380); 180 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", -2147483647, 400, "integer"); 181 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? min(2147483647, PHP_INT_MAX) : 1, 420); 182 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", NULL, 440); 183 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, 2147483647) : 1, 460); 184 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", 4294967295, 480, (defined("PHP_INT_MAX") && (4294967295 > PHP_INT_MAX)) ? "string" : null); 185 func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", NULL, 500); 186 187 /* test is broken too: we bind "integer" but value is a float 188 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -9223372036854775808, 520); 189 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 18446744073709551615, 560); 190 */ 191 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", NULL, 540); 192 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", NULL, 580); 193 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1, 1780); 194 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 1, 1800); 195 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); 196 func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); 197 func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); 198 func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); 199 200 func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); 201 func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", NULL, 620); 202 func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); 203 func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); 204 205 // Yes, we need the temporary variable. The PHP casting will foul us otherwise. 206 $tmp = strval('-99999999.99'); 207 func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); 208 func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); 209 $tmp = strval('99999999.99'); 210 func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); 211 func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); 212 $tmp = strval('-99999999.99'); 213 func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); 214 func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); 215 $tmp = strval('99999999.99'); 216 func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); 217 func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); 218 219 // don't care about date() strict TZ warnings... 220 func_mysqli_stmt_bind_result($link, $engine, "s", "DATE", @date('Y-m-d'), 840); 221 func_mysqli_stmt_bind_result($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 860); 222 func_mysqli_stmt_bind_result($link, $engine, "s", "DATE", NULL, 880); 223 224 func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 900); 225 func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 920); 226 func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME", NULL, 940); 227 228 func_mysqli_stmt_bind_result($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 960); 229 230 func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", @date('H:i:s'), 980); 231 func_mysqli_stmt_bind_result($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 1000); 232 func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", NULL, 1020); 233 234 $tmp = intval(@date('Y')); 235 func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); 236 func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); 237 func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", NULL, 1080); 238 239 $string255 = func_mysqli_stmt_bind_make_string(255); 240 func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1)", "a", 1110, 'string'); 241 func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(255)", $string255, 1120, 'string'); 242 func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1) NOT NULL", "a", 1140, 'string'); 243 func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1)", NULL, 1160); 244 245 $string65k = func_mysqli_stmt_bind_make_string(65535); 246 func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1)", "a", 1180, 'string'); 247 func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(255)", $string255, 1200, 'string'); 248 func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(65635)", $string65k, 1220, 'string'); 249 func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 1240, 'string'); 250 func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1)", NULL, 1260); 251 252 func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", "a", 1280); 253 func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", chr(0), 1300); 254 func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1) NOT NULL", "b", 1320); 255 func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", NULL, 1340); 256 257 func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", "a", 1360); 258 func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", chr(0), 1380); 259 func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 1400); 260 func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", NULL, 1420); 261 262 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", "a", 1440); 263 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", chr(0), 1460); 264 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB NOT NULL", "b", 1480); 265 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", NULL, 1500); 266 267 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT", "a", 1520, 'string'); 268 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT NOT NULL", "a", 1540, 'string'); 269 func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT", NULL, 1560, 'string'); 270 271 // Note: you cannot insert any blob values this way. But you can check the API at least partly this way 272 // Extra BLOB tests are in mysqli_stmt_send_long() 273 func_mysqli_stmt_bind_result($link, $engine, "b", "BLOB", "", 1580); 274 func_mysqli_stmt_bind_result($link, $engine, "b", "TEXT", "", 1600, 'string'); 275 func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMBLOB", "", 1620); 276 func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMTEXT", "", 1640, 'string'); 277 278 /* Is this one related? http://bugs.php.net/bug.php?id=35759 */ 279 func_mysqli_stmt_bind_result($link, $engine, "b", "LONGBLOB", "", 1660); 280 func_mysqli_stmt_bind_result($link, $engine, "b", "LONGTEXT", "", 1680, 'string'); 281 282 func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", "a", 1700, 'string'); 283 func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", NULL, 1720, 'string'); 284 func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", "a", 1740, 'string'); 285 func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", NULL, 1760, 'string'); 286 287 if (mysqli_get_server_version($link) >= 50600) 288 func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", "13:31:34.123456", 1770, "13:31:34"); 289 290 $stmt = mysqli_stmt_init($link); 291 if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1000, 'z')")) 292 printf("[3001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 293 294 $id = null; 295 try { 296 mysqli_stmt_bind_result($stmt, $id); 297 } catch (\ArgumentCountError $e) { 298 $e->getMessage() . \PHP_EOL; 299 } 300 301 mysqli_stmt_close($stmt); 302 303 mysqli_close($link); 304 print "done!"; 305?> 306--CLEAN-- 307<?php 308 require_once("clean_table.inc"); 309?> 310--EXPECTF-- 311mysqli_stmt object is not fully initialized 312Number of bind variables doesn't match number of fields in prepared statement 313Number of bind variables doesn't match number of fields in prepared statement 314int(1) 315%s(1) "a" 316done! 317