1--TEST-- 2mysqli_store_result() 3--SKIPIF-- 4<?php 5require_once('skipif.inc'); 6require_once('skipifconnectfailure.inc'); 7if (!$IS_MYSQLND) { 8 die("SKIP mysqlnd only test"); 9} 10?> 11--INI-- 12mysqlnd.debug="d:t:O,{TMP}/mysqlnd.trace" 13mysqlnd.net_read_buffer_size=1 14mysqlnd.mempool_default_size=1 15mysqlnd.fetch_data_copy=0 16--FILE-- 17<?php 18 require_once("connect.inc"); 19 20 $tmp = NULL; 21 $link = NULL; 22 23 require('table.inc'); 24 25 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) 26 printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 27 28 if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) 29 printf("[004] Expecting object, got %s/%s. [%d] %s\n", 30 gettype($res), $res, mysqli_errno($link), mysqli_error($link)); 31 32 if (true !== ($tmp = mysqli_data_seek($res, 2))) 33 printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n", 34 gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); 35 36 var_dump($res->fetch_assoc()); 37 38 if (true !== ($tmp = mysqli_data_seek($res, 0))) 39 printf("[006] Expecting boolean/true, got %s/%s. [%d] %s\n", 40 gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); 41 42 while ($row = $res->fetch_assoc()) { 43 printf("id = %d, label = %s\n", $row['id'], $row['label']); 44 } 45 46 mysqli_free_result($res); 47 mysqli_close($link); 48 49 if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { 50 printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", 51 $host, $user, $db, $port, $socket); 52 } 53 54 55 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) 56 printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 57 58 if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) 59 printf("[009] Expecting object, got %s/%s. [%d] %s\n", 60 gettype($res), $res, mysqli_errno($link), mysqli_error($link)); 61 62 $no_result = 0; 63 for ($i = 0; $i < 1000; $i++) { 64 $idx = mt_rand(-100, 100); 65 try { 66 if (true === @mysqli_data_seek($res, $idx)) { 67 $row = $res->fetch_assoc(); 68 if (!isset($row['id']) || !isset($row['label'])) { 69 printf("[010] Brute force seek %d returned %d\n", $idx, var_export($row, true)); 70 } 71 } else { 72 $no_result++; 73 } 74 } catch (\ValueError $e) { 75 $no_result++; 76 } 77 } 78 printf("No result: %d\n", $no_result); 79 80 /* implicit free, implicit store */ 81 /* meta and fetch lengths code */ 82 if (!$res = mysqli_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2")) 83 printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 84 85 printf("Default\n"); 86 var_dump(mysqli_fetch_lengths($res)); 87 $fields = $res->fetch_fields(); 88 while ($row = $res->fetch_assoc()) { 89 var_dump(mysqli_fetch_lengths($res)); 90 } 91 var_dump(mysqli_fetch_lengths($res)); 92 93 if (!$res = mysqli_real_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2")) 94 printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 95 96 if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) 97 printf("[013] Expecting object, got %s/%s. [%d] %s\n", 98 gettype($res), $res, mysqli_errno($link), mysqli_error($link)); 99 100 printf("Copy\n"); 101 var_dump(mysqli_fetch_lengths($res)); 102 $fields_copy = $res->fetch_fields(); 103 while ($row = $res->fetch_assoc()) { 104 var_dump(mysqli_fetch_lengths($res)); 105 } 106 var_dump(mysqli_fetch_lengths($res)); 107 108 /* There's no need for in-depth testing here. If you want in-depth switch mysqlnd 109 globally to copy mode and run all the tests */ 110 foreach ($fields as $k => $field_info) { 111 if ($fields_copy[$k] != $field_info) { 112 printf("[014] Metadata seems to differ, dumping\n"); 113 var_dump($field_info); 114 var_dump($fields_copy[$k]); 115 } 116 } 117 118 /* fetch all */ 119 120 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) 121 printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 122 123 if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) 124 printf("[016] Expecting object, got %s/%s. [%d] %s\n", 125 gettype($res), $res, mysqli_errno($link), mysqli_error($link)); 126 127 foreach (mysqli_fetch_all($res, MYSQLI_ASSOC) as $row) { 128 printf("id = %d label = %s\n", $row['id'], $row['label']); 129 } 130 131 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) 132 printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 133 134 if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) 135 printf("[018] Expecting object, got %s/%s. [%d] %s\n", 136 gettype($res), $res, mysqli_errno($link), mysqli_error($link)); 137 138 /* provoke out of sync */ 139 if (!mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) 140 printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 141 142 var_dump($res->fetch_assoc()); 143 144 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) 145 printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 146 147 if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) 148 printf("[021] Expecting object, got %s/%s. [%d] %s\n", 149 gettype($res), $res, mysqli_errno($link), mysqli_error($link)); 150 151 /* user conn killed, res associated with conn, fetch from res */ 152 unset($link); 153 var_dump($res->fetch_assoc()); 154 155 156 if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { 157 printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", 158 $host, $user, $db, $port, $socket); 159 } 160 161 if (!$res = mysqli_real_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')")) 162 printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 163 164 mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA); 165 166 if (mysqli_get_server_version($link) > 50000) { 167 // let's try to play with stored procedures 168 mysqli_real_query($link, 'DROP PROCEDURE IF EXISTS p'); 169 if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) READS SQL DATA BEGIN SELECT id FROM test WHERE id >= 100 ORDER BY id; SELECT id + 1, label FROM test WHERE id > 0 AND id < 3 ORDER BY id; SELECT VERSION() INTO ver_param; 170END;')) { 171 mysqli_multi_query($link, "CALL p(@version)"); 172 do { 173 if ($res = $link->store_result(MYSQLI_STORE_RESULT_COPY_DATA)) { 174 printf("---\n"); 175 var_dump($res->fetch_all()); 176 $res->free(); 177 } else { 178 if ($link->errno) { 179 echo "Store failed: (" . $link->errno . ") " . $link->error; 180 } 181 } 182 } while ($link->more_results() && $link->next_result()); 183 mysqli_real_query($link, 'SELECT @version AS p_version'); 184 $res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA); 185 186 $tmp = mysqli_fetch_assoc($res); 187 if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) { 188 printf("[024] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 189 var_dump($tmp); 190 } 191 192 mysqli_free_result($res); 193 } else { 194 printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 195 } 196 } 197 198 print "done!"; 199?> 200--CLEAN-- 201<?php 202 require_once("clean_table.inc"); 203?> 204--EXPECTF-- 205array(2) { 206 ["id"]=> 207 string(1) "3" 208 ["label"]=> 209 string(1) "c" 210} 211id = 1, label = a 212id = 2, label = b 213id = 3, label = c 214id = 4, label = d 215id = 5, label = e 216id = 6, label = f 217No result: %d 218Default 219bool(false) 220array(2) { 221 [0]=> 222 int(2) 223 [1]=> 224 int(1) 225} 226array(2) { 227 [0]=> 228 int(2) 229 [1]=> 230 int(1) 231} 232bool(false) 233Copy 234bool(false) 235array(2) { 236 [0]=> 237 int(2) 238 [1]=> 239 int(1) 240} 241array(2) { 242 [0]=> 243 int(2) 244 [1]=> 245 int(1) 246} 247bool(false) 248id = 6 label = f 249id = 5 label = e 250array(2) { 251 ["id"]=> 252 string(1) "6" 253 ["label"]=> 254 string(1) "f" 255} 256[020] [2014] %s 257array(2) { 258 ["id"]=> 259 string(1) "6" 260 ["label"]=> 261 string(1) "f" 262} 263--- 264array(1) { 265 [0]=> 266 array(1) { 267 [0]=> 268 string(3) "100" 269 } 270} 271--- 272array(2) { 273 [0]=> 274 array(2) { 275 [0]=> 276 string(1) "2" 277 [1]=> 278 string(1) "a" 279 } 280 [1]=> 281 array(2) { 282 [0]=> 283 string(1) "3" 284 [1]=> 285 string(1) "b" 286 } 287} 288done! 289