--TEST-- mysqli_stmt_bind_result() --SKIPIF-- --FILE-- ') == 1) ? "unicode":"string"; $tmp = NULL; $link = NULL; if (!is_null($tmp = @mysqli_stmt_bind_result())) printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); if (!is_null($tmp = @mysqli_stmt_bind_result($link))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); require('table.inc'); $stmt = mysqli_stmt_init($link); if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) printf("[002a] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (!is_null($tmp = @mysqli_stmt_bind_result($stmt))) printf("[002b] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); mysqli_stmt_close($stmt); $stmt = mysqli_stmt_init($link); $id = null; $label = null; $foo = null; if (!is_null($tmp = mysqli_stmt_bind_result($stmt))) printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id))) printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label, $foo))) printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); if (!mysqli_stmt_execute($stmt)) printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); while (mysqli_stmt_fetch($stmt)) { var_dump($id); var_dump($label); } mysqli_stmt_close($stmt); function func_mysqli_stmt_bind_result($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $type_hint = null) { if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) { printf("[%04d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link)); return false; } if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) { // don't bail - column type might not be supported by the server, ignore this return false; } if (!$stmt = mysqli_stmt_init($link)) { printf("[%04d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link)); return false; } if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) { printf("[%04d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); return false; } $id = null; if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) { printf("[%04d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); mysqli_stmt_close($stmt); return false; } for ($id = 1; $id < 4; $id++) { if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 3 + $id, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); mysqli_stmt_close($stmt); return false; } } mysqli_stmt_close($stmt); $stmt = mysqli_stmt_init($link); if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) { printf("[%04d] [%d] %s\n", $offset + 7, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); mysqli_stmt_close($stmt); return false; } if (!mysqli_stmt_execute($stmt)) { printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); mysqli_stmt_close($stmt); return false; } $result = mysqli_stmt_result_metadata($stmt); $bind_res = null; if (!mysqli_stmt_bind_result($stmt, $id, $bind_res)) { printf("[%04d] [%d] %s\n", $offset + 9, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); mysqli_stmt_close($stmt); return false; } $num = 0; $fields = mysqli_fetch_fields($result); while (mysqli_stmt_fetch($stmt)) { if (!gettype($bind_res)=="unicode") { if ($bind_res !== $bind_value && (!$type_hint || ($type_hint !== gettype($bind_res)))) { printf("[%04d] [%d] Expecting %s/'%s' [type hint = %s], got %s/'%s'\n", $offset + 10, $num, gettype($bind_value), $bind_value, $type_hint, gettype($bind_res), $bind_res); mysqli_stmt_close($stmt); return false; } } $num++; } if ($num != 3) { printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); mysqli_stmt_close($stmt); return false; } mysqli_stmt_close($stmt); return true; } function func_mysqli_stmt_bind_make_string($len) { $ret = ''; for ($i = 0; $i < $len; $i++) $ret .= chr(mt_rand(65, 90)); return $ret; } func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT", -11, 20); func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT", NULL, 40); func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT UNSIGNED", 1, 60); func_mysqli_stmt_bind_result($link, $engine, "i", "TINYINT UNSIGNED", NULL, 80); func_mysqli_stmt_bind_result($link, $engine, "i", "BOOL", 1, 100); func_mysqli_stmt_bind_result($link, $engine, "i", "BOOL", NULL, 120); func_mysqli_stmt_bind_result($link, $engine, "i", "BOOLEAN", 0, 140); func_mysqli_stmt_bind_result($link, $engine, "i", "BOOLEAN", NULL, 160); func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", -32768, 180); func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", 32767, 200); func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT", NULL, 220); func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 240); func_mysqli_stmt_bind_result($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 260); func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", -8388608, 280, "integer"); func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", 8388607, 300, "integer"); func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT", NULL, 320); func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT UNSIGNED", 16777215, 340, "integer"); func_mysqli_stmt_bind_result($link, $engine, "d", "MEDIUMINT UNSIGNED", NULL, 360); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? max(-1 * PHP_INT_MAX + 1, -2147483648) : 1, 380); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", -2147483647, 400, "integer"); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", (defined("PHP_INT_MAX")) ? min(2147483647, PHP_INT_MAX) : 1, 420); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER", NULL, 440); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, 2147483647) : 1, 460); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", 4294967295, 480, (defined("PHP_INT_MAX") && (4294967295 > PHP_INT_MAX)) ? "string" : null); func_mysqli_stmt_bind_result($link, $engine, "i", "INTEGER UNSIGNED", NULL, 500); /* test is broken too: we bind "integer" but value is a float func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -9223372036854775808, 520); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 18446744073709551615, 560); */ func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", NULL, 540); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", NULL, 580); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1, 1780); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", 1, 1800); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 1820); func_mysqli_stmt_bind_result($link, $engine, "i", "BIGINT UNSIGNED", PHP_INT_MAX, 1840); func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 1860); func_mysqli_stmt_bind_result($link, $engine, "s", "BIGINT", "-9223372036854775808", 1880); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 600); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT", NULL, 620); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 640); func_mysqli_stmt_bind_result($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 660); // Yes, we need the temporary variable. The PHP casting will fouls us otherwise. $tmp = strval('-99999999.99'); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", $tmp, 680, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2)", NULL, 700); $tmp = strval('99999999.99'); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", $tmp , 720, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 740); $tmp = strval('-99999999.99'); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 760, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 780); $tmp = strval('99999999.99'); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", $tmp, 800, "string"); func_mysqli_stmt_bind_result($link, $engine, "d", "DECIMAL(10,2)", NULL, 820); // don't care about date() strict TZ warnings... func_mysqli_stmt_bind_result($link, $engine, "s", "DATE", @date('Y-m-d'), 840); func_mysqli_stmt_bind_result($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 860); func_mysqli_stmt_bind_result($link, $engine, "s", "DATE", NULL, 880); func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 900); func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 920); func_mysqli_stmt_bind_result($link, $engine, "s", "DATETIME", NULL, 940); func_mysqli_stmt_bind_result($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 960); func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", @date('H:i:s'), 980); func_mysqli_stmt_bind_result($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 1000); func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", NULL, 1020); $tmp = intval(@date('Y')); func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", $tmp, 1040, "integer"); func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR NOT NULL", $tmp, 1060, "integer"); func_mysqli_stmt_bind_result($link, $engine, "s", "YEAR", NULL, 1080); $string255 = func_mysqli_stmt_bind_make_string(255); func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1)", "a", 1110, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(255)", $string255, 1120, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1) NOT NULL", "a", 1140, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "CHAR(1)", NULL, 1160); $string65k = func_mysqli_stmt_bind_make_string(65535); func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1)", "a", 1180, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(255)", $string255, 1200, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(65635)", $string65k, 1220, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 1240, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "VARCHAR(1)", NULL, 1260); func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", "a", 1280); func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", chr(0), 1300); func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1) NOT NULL", "b", 1320); func_mysqli_stmt_bind_result($link, $engine, "s", "BINARY(1)", NULL, 1340); func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", "a", 1360); func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", chr(0), 1380); func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 1400); func_mysqli_stmt_bind_result($link, $engine, "s", "VARBINARY(1)", NULL, 1420); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", "a", 1440); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", chr(0), 1460); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB NOT NULL", "b", 1480); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYBLOB", NULL, 1500); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT", "a", 1520, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT NOT NULL", "a", 1540, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "TINYTEXT", NULL, 1560, $hint_str_or_unicode); // Note: you cannot insert any blob values this way. But you can check the API at least partly this way // Extra BLOB tests are in mysqli_stmt_send_long() func_mysqli_stmt_bind_result($link, $engine, "b", "BLOB", b"", 1580); func_mysqli_stmt_bind_result($link, $engine, "b", "TEXT", "", 1600, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMBLOB", b"", 1620); func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMTEXT", "", 1640, $hint_str_or_unicode); /* Is this one related? http://bugs.php.net/bug.php?id=35759 */ if (($IS_MYSQLND) || (!$IS_MYSQLND && (ini_get('memory_limit') > 4294967296))) { /* NOTE: the MySQL Client Library - not mysqlnd - will allocate a hugge max_length(type) = 4GB bind buffer */ func_mysqli_stmt_bind_result($link, $engine, "b", "LONGBLOB", "", 1660); func_mysqli_stmt_bind_result($link, $engine, "b", "LONGTEXT", "", 1680, $hint_str_or_unicode); } func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", "a", 1700, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", NULL, 1720, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", "a", 1740, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "SET('a', 'b')", NULL, 1760, $hint_str_or_unicode); if (mysqli_get_server_version($link) >= 50600) func_mysqli_stmt_bind_result($link, $engine, "s", "TIME", "13:31:34.123456", 1770, "13:31:34"); /* Check that the function alias exists. It's a deprecated function, but we have not announce the removal so far, therefore we need to check for it */ if (!is_null($tmp = @mysqli_stmt_bind_result())) printf("[3000] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); $stmt = mysqli_stmt_init($link); if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (1000, 'z')")) printf("[3001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); $id = null; if (false !== @mysqli_stmt_bind_result($stmt, $id)) printf("[3002] Bind result should not be allowed"); mysqli_stmt_close($stmt); mysqli_close($link); print "done!"; ?> --CLEAN-- --EXPECTF-- Warning: mysqli_stmt_bind_result(): invalid object or resource mysqli_stmt in %s on line %d Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d int(1) %s(1) "a" done!