1--TEST-- 2mysqli_stmt_attr_set() - mysqlnd does not check for invalid codes 3--EXTENSIONS-- 4mysqli 5--SKIPIF-- 6<?php 7require_once 'skipifconnectfailure.inc'; 8?> 9--FILE-- 10<?php 11 require 'table.inc'; 12 13 $stmt = mysqli_stmt_init($link); 14 try { 15 mysqli_stmt_attr_set($stmt, 0, 0); 16 } catch (\Throwable $e) { 17 echo get_class($e) . ': ' . $e->getMessage() . PHP_EOL; 18 } 19 20 $stmt->prepare("SELECT * FROM test"); 21 // Invalid Attribute (2nd argument) 22 try { 23 mysqli_stmt_attr_set($stmt, -1, 0); 24 } catch (\ValueError $e) { 25 echo $e->getMessage() . \PHP_EOL; 26 } 27 // Invalid mode for MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 28 try { 29 $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, -1); 30 } catch (\ValueError $e) { 31 echo $e->getMessage() . \PHP_EOL; 32 } 33 $stmt->close(); 34 35 // 36 // MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 37 // 38 // expecting max_length not to be set and be 0 in all cases 39 $stmt = mysqli_stmt_init($link); 40 $stmt->prepare("SELECT label FROM test"); 41 $stmt->execute(); 42 $stmt->store_result(); 43 $res = $stmt->result_metadata(); 44 $fields = $res->fetch_fields(); 45 foreach ($fields as $meta) { 46 if ($meta->max_length !== 0) 47 printf("[007] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); 48 } 49 $res->close(); 50 $stmt->close(); 51 52 // MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH is no longer supported, expect no change in behavior. 53 $stmt = mysqli_stmt_init($link); 54 $stmt->prepare("SELECT label FROM test"); 55 var_dump($stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1)); 56 $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); 57 if ($res !== 1) 58 printf("[007.1] max_length should be 1, got %s\n", $res); 59 $stmt->execute(); 60 $stmt->store_result(); 61 $res = $stmt->result_metadata(); 62 $fields = $res->fetch_fields(); 63 foreach ($fields as $meta) { 64 if ($meta->max_length !== 0) 65 printf("[008] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); 66 } 67 $res->close(); 68 $stmt->close(); 69 70 // expecting max_length not to be set 71 $stmt = mysqli_stmt_init($link); 72 $stmt->prepare("SELECT label FROM test"); 73 $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 0); 74 $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); 75 if ($res !== 0) 76 printf("[008.1] max_length should be 0, got %s\n", $res); 77 $stmt->execute(); 78 $stmt->store_result(); 79 $res = $stmt->result_metadata(); 80 $fields = $res->fetch_fields(); 81 foreach ($fields as $meta) { 82 if ($meta->max_length !== 0) 83 printf("[009] max_length should not be set (= 0), got %s for field %s\n", $meta->max_length, $meta->name); 84 } 85 $res->close(); 86 $stmt->close(); 87 88 // 89 // Cursors 90 // 91 92 93 $stmt = mysqli_stmt_init($link); 94 $stmt->prepare("SELECT id, label FROM test"); 95 96 // Invalid cursor type 97 try { 98 $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, -1); 99 } catch (\ValueError $e) { 100 echo $e->getMessage() . \PHP_EOL; 101 } 102 103 if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR))) 104 printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); 105 106 if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY))) 107 printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); 108 109 $stmt->close(); 110 111 $stmt = mysqli_stmt_init($link); 112 $stmt->prepare("SELECT id, label FROM test"); 113 $stmt->execute(); 114 $id = $label = NULL; 115 $stmt->bind_result($id, $label); 116 $results = array(); 117 while ($stmt->fetch()) 118 $results[$id] = $label; 119 $stmt->close(); 120 if (empty($results)) 121 printf("[015] Results should not be empty, subsequent tests will probably fail!\n"); 122 123 $stmt = mysqli_stmt_init($link); 124 $stmt->prepare("SELECT id, label FROM test"); 125 if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR))) 126 printf("[016] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); 127 $stmt->execute(); 128 $id = $label = NULL; 129 $stmt->bind_result($id, $label); 130 $results2 = array(); 131 while ($stmt->fetch()) 132 $results2[$id] = $label; 133 $stmt->close(); 134 if ($results != $results2) { 135 printf("[017] Results should not differ. Dumping both result sets.\n"); 136 var_dump($results); 137 var_dump($results2); 138 } 139 140 $stmt = mysqli_stmt_init($link); 141 $stmt->prepare("SELECT id, label FROM test"); 142 if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY))) 143 printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); 144 $stmt->execute(); 145 $id = $label = NULL; 146 $stmt->bind_result($id, $label); 147 $results2 = array(); 148 while ($stmt->fetch()) 149 $results2[$id] = $label; 150 $stmt->close(); 151 if ($results != $results2) { 152 printf("[019] Results should not differ. Dumping both result sets.\n"); 153 var_dump($results); 154 var_dump($results2); 155 } 156 157 mysqli_close($link); 158 print "done!"; 159?> 160--CLEAN-- 161<?php 162 require_once 'clean_table.inc'; 163?> 164--EXPECT-- 165Error: mysqli_stmt object is not fully initialized 166mysqli_stmt_attr_set(): Argument #2 ($attribute) must be either MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH or MYSQLI_STMT_ATTR_CURSOR_TYPE 167mysqli_stmt::attr_set(): Argument #2 ($value) must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 168bool(true) 169mysqli_stmt::attr_set(): Argument #2 ($value) must be one of the MYSQLI_CURSOR_TYPE_* constants for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE 170done! 171