1--TEST-- 2mysqli_stmt_execute() - bind in execute 3--EXTENSIONS-- 4mysqli 5--SKIPIF-- 6<?php 7require_once 'skipifconnectfailure.inc'; 8if (!$IS_MYSQLND) { 9 die("skip only available in mysqlnd"); 10} 11?> 12--FILE-- 13<?php 14require_once "connect.inc"; 15 16require 'table.inc'; 17 18mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 19 20// first, control case 21$id = 1; 22$abc = 'abc'; 23$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 24$stmt->bind_param('sss', ...[&$abc, 42, $id]); 25$stmt->execute(); 26assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); 27$stmt = null; 28 29// 1. same as the control case, but skipping the middle-man (bind_param) 30$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 31$stmt->execute([&$abc, 42, $id]); 32assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); 33$stmt = null; 34 35// 2. param number has to match - missing 1 parameter 36$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 37try { 38 $stmt->execute([&$abc, 42]); 39} catch (ValueError $e) { 40 echo '[001] '.$e->getMessage()."\n"; 41} 42$stmt = null; 43 44// 3. Too many parameters 45$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 46try { 47 $stmt->execute([&$abc, null, $id, 24]); 48} catch (ValueError $e) { 49 echo '[002] '.$e->getMessage()."\n"; 50} 51$stmt = null; 52 53// 4. param number has to match - missing all parameters 54$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 55try { 56 $stmt->execute([]); 57} catch (ValueError $e) { 58 echo '[003] '.$e->getMessage()."\n"; 59} 60$stmt = null; 61 62// 5. param number has to match - missing argument to execute() 63$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 64try { 65 $stmt->execute(); 66} catch (mysqli_sql_exception $e) { 67 echo '[004] '.$e->getMessage()."\n"; 68} 69$stmt = null; 70 71// 6. wrong argument to execute() 72$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 73try { 74 $stmt->execute(42); 75} catch (TypeError $e) { 76 echo '[005] '.$e->getMessage()."\n"; 77} 78$stmt = null; 79 80// 7. objects are not arrays and are not accepted 81$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 82try { 83 $stmt->execute((object)[&$abc, 42, $id]); 84} catch (TypeError $e) { 85 echo '[006] '.$e->getMessage()."\n"; 86} 87$stmt = null; 88 89// 8. arrays by reference work too 90$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 91$arr = [&$abc, 42, $id]; 92$arr2 = &$arr; 93$stmt->execute($arr2); 94assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); 95$stmt = null; 96 97// 9. no placeholders in statement. nothing to bind in an empty array 98$stmt = $link->prepare('SELECT label FROM test WHERE id=1'); 99$stmt->execute([]); 100assert($stmt->get_result()->fetch_assoc() === ['label'=>'a']); 101$stmt = null; 102 103// 10. once bound the values are persisted. Just like in PDO 104$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 105$stmt->execute(['abc', 42, $id]); 106assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); 107$stmt->execute(); // no argument here. Values are already bound 108assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); 109try { 110 $stmt->execute([]); // no params here. PDO doesn't throw an error, but mysqli does 111} catch (ValueError $e) { 112 echo '[007] '.$e->getMessage()."\n"; 113} 114$stmt = null; 115 116// 11. mixing binding styles not possible. Also, NULL should stay NULL when bound as string 117$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 118$stmt->bind_param('sss', ...['abc', 42, null]); 119$stmt->execute([null, null, $id]); 120assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>null, 'num' => null]); 121$stmt = null; 122 123// 12. Only list arrays are allowed 124$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); 125try { 126 $stmt->execute(['A'=>'abc', 2=>42, null=>$id]); 127} catch (ValueError $e) { 128 echo '[008] '.$e->getMessage()."\n"; 129} 130$stmt = null; 131 132 133mysqli_close($link); 134?> 135--CLEAN-- 136<?php 137require_once "clean_table.inc"; 138?> 139--EXPECT-- 140[001] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 2 present 141[002] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 4 present 142[003] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 0 present 143[004] No data supplied for parameters in prepared statement 144[005] mysqli_stmt::execute(): Argument #1 ($params) must be of type ?array, int given 145[006] mysqli_stmt::execute(): Argument #1 ($params) must be of type ?array, stdClass given 146[007] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 0 present 147[008] mysqli_stmt::execute(): Argument #1 ($params) must be a list array 148