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