I am writing a search function that will be used to query students. I am trying to dynamically use the mysqli_stmt_bind_param function but am not having any success. I know this question has been asked before on here, but I have not encountered my specific need yet. Please help me understand why what I am doing is not working.
Essentially, I am trying to find out how to dynamically bind parameters if I am not sure how many parameters to bind. There are 5 different possible "affixes" to the main SQL statement, and any combination could be generated, yielding impossibly long different combinations.
I am trying an approach as seen under // Binder // but this is not yielding the desired result. How should I go about solving this problem?
function roster($json) {
require 'dbh.int.php';
$parms = json_decode($json, true);
$SQL = "SELECT students.* FROM students INNER JOIN enrollments ON students.usid = enrollments.usid INNER JOIN sections ON enrollments.sectionID = sections.sectionID WHERE firstName IS NOT NULL";
if (isset($parms['sectionID'])) {$SQL .= " AND sectionID=?"; $binders[] = $parms['sectionID'];}
if (isset($parms['siteID'])) {$SQL .= " AND siteID=?"; $binders[] = $parms['siteID'];}
if (isset($parms['grade'])) {$SQL .= " AND grade=?"; $binders[] = $parms['grade'];}
if (isset($parms['ueid'])) {$SQL .= " AND ueid=?"; $binders[] = $parms['ueid'];}
if (isset($parms['search'])) {$SQL .= " AND (firstName LIKE ? OR lastName LIKE ? OR email LIKE ?)";}
$stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($stmt, $SQL)) {return "SQL database error";}
else {
// Binder //
$length = substr_count($SQL, '?');
$qmark = ''; for ($i = 1; $i <= $length; $i++) {$qmark .= 's';}
$qmarks = array($qmark);
$merge = array_merge($qmarks, $binders);
call_user_func_array(array($stmt, 'bind_param'), $merge);
// Executor //
mysqli_stmt_execute($stmt) or die(mysqli_error($connection));
$results = mysqli_stmt_get_result($stmt);
if ($row = mysqli_num_rows($results) == 0) {return $SQL;}
else {
while ($row = mysqli_fetch_assoc($results)) {
foreach ($row AS $key => $value) {
if (isset($value)) {$array[$row['usid']][$key] = $value;}
}
}
return $array;
}
}
}
>Solution :
The values in $binders should be the values of the $params strings, not literal strings containing $params references. So
$binders[] = '$parms[\'sectionID\']';
should be
$binders[] = &$parms['sectionID'];
Notice also that you have to put & before the variable name to make it a reference.
You’re mixing procedural and OO code in your call_user_func_array. mysqli_stmt_bind_param is a regular function, not a method name. The method is bind_param.
call_user_func_array(array($stmt, 'bind_param'), $params);