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