1

My code to generate the SQL statement works fine - however I run into a hiccup when generating the string for $stmt->bind_param(). Code is as follows:

$stmt = $mysqli->stmt_init();
if ($stmt->prepare ($sql)) {
    $bind_types = '"';
    $bind_values = '';

    if ($action == 'insert' || $action == 'update') {
        reset ($array);
        foreach ($array as $key => $value) {
            if (is_string ($value)) { $type = 's'; } else if (is_int ($value)) { $type = 'i'; } else if (is_float ($value)) { $type = 'd'; } else { die ('Cannot determine type for ' . $key . ' => ' . $value . ''); }
            $bind_types .= $type;
            $bind_values .= $value . ', ';
            //$stmt->bind_param ($type, $value);
        }
    }
    
    if ($action == 'update' || $action == 'delete') {
        if (is_string ($id_value)) { $type = 's'; } else if (is_int ($id_value)) { $type = 'i'; } else if (is_float ($id_value)) { $type = 'd'; } else { die ('Cannot determine type for ' . $id_column . ' => ' . $id_value . ''); }
        $bind_types .= $type;
        $bind_values .= $id_value . ', ';
        //$stmt->bind_param ($type, $id_value);
    }
    
    $bind_types .= '"';
    
    $bind_values = substr ($bind_values, 0, -2);
    
    echo $bind_types  . ', ' . $bind_values;
    
    $stmt->bind_param ($bind_types, $bind_values);
    $stmt->execute();
    
}

The formatting of that got messed up. I apologize if its hard to read.

I am getting the following error:

"Warning: mysqli_stmt::bind_param() [mysqli-stmt.bind-param]: Number of elements in type definition string doesn't match number of bind variables in ... "

Any ideas?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Luke Pittman
  • 870
  • 4
  • 12
  • So much `mysql_` and `mysqli` in the last hour... use [PDO](http://us2.php.net/manual/en/book.pdo.php) instead. – Waleed Khan Jul 18 '12 at 02:32
  • I was looking into it. However the arguments for using mysqli vs. PDO are good on both sides. I figured mysqli was the way to roll. Maybe not. – Luke Pittman Jul 18 '12 at 02:33
  • I wasn't under the impression that there was much of an argument, but I will go view said arguments now. – Waleed Khan Jul 18 '12 at 02:35
  • @LukePittman you will find that it usually not worth specifying the data types for the binding call. Using `s` for each variable is generally enough. You might prefer the cleanliness of [this approach](https://stackoverflow.com/a/51036322/2943403) -- you should have no trouble adapting it to uour needs. – mickmackusa Apr 03 '22 at 09:07

2 Answers2

3

I would highly advise to use PDO as you can do it easily. If you want to do it in mysqli it is more complicated since you can't easily bind them dynamically. To bind them dynamically look at this ugly hack

$bind_values= explode(',', $bind_values);
call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($bind_values));
$stmt->execute();

function makeValuesReferenced(&$arr){ 
    $refs = array(); 
    foreach($arr as $key => $value) 
        $refs[$key] = &$arr[$key]; 
    return $refs; 

}
Kris
  • 6,094
  • 2
  • 31
  • 46
  • I am looking at PDO right now and will most likely migrate this test code over to that to test it out. Additionally you actually answered my question, so thanks. – Luke Pittman Jul 18 '12 at 02:48
0

Your call to bind_param is wrong: it should be:

bind_param($types, $value1, $value2, $value3 ...);

where each of those values is an actual variable.

Waleed Khan
  • 11,426
  • 6
  • 39
  • 70