0

I understand that we have to pass references to mysqli_stmt_bind_param. I am doing the following

    $ref = refValues($data);
    function refValues($arr){
        $refs = array();
        foreach($arr as $key => $value)
            $refs[$key] = &$arr[$key];
            var_dump(implode(",", $refs));
            return $refs;
    return $arr;
}

I am having all of my values in an array. I am using the above function to get the references. Got the above answer from SO

My PHP version is 5.6

I am binding the params in the following way.

mysqli_stmt_bind_param($stmt, $types, $ref);

$stmt is a statement created through mysqli_prepare. It returns error number 0.

$types is nothing but $types = str_pad('',count($data),'s');

I have verified $types data also. It returns expected number of types. i.e ssssssss

If I execute, I am getting the following error.

 Only variables should be passed by reference in test.php

I found this solution in SO. I cannot assign 100 variables. I am not thinking that is feasible.

I found another alternative is call_user_func_arrary.

$values =  refValues($data);
call_user_func_array(array($stmt, 'bind_param'), $values);

It returns number of bind type doesn't match number of values. It is weird for me. I have verified the array and values. Both counts are matching. I am not aware of internal implementation of call_user_func_array.

Please let me know is there any way to solve this efficiently.

Community
  • 1
  • 1
Gibbs
  • 21,904
  • 13
  • 74
  • 138

2 Answers2

3

This line

mysqli_stmt_bind_param($stmt, $types, $ref);

means that you have one reference to bind.

Why? Let's see:

  • first argument is a statement
  • second argument is a string with types
  • following arguments are references to values which should be binded.

As you pass one argument (it is $ref) - you are trying to bind only one value. And $ref is not a reference, it is array of values which are refernces. See the difference? Array of references vs reference.

So, you took second approach, and it is a right one:

$values =  refValues($data);
call_user_func_array(array($stmt, 'bind_param'), $values);

What's the error here? You didn't pass types $types:

// do not assign anything to a variable
// pass results of `refValues` directly to `call_user_func_array`
call_user_func_array(array($stmt, 'bind_param'), array_merge(array($types), refValues($data)));

What do we do here: we are trying to call $stmt->bind_param and pass to this function arguments as array.

What are the arguments of $stmt->bind_param?

  • first argument is types ($types)
  • following arguments are references to values ($values)

Now it should work.

u_mulder
  • 54,101
  • 5
  • 48
  • 64
2

There are two possible ways to avoid this hassle:

  1. Use PDO. Your current problem is only the first out of many WTFs you will have with mysqli. In this particular case it would be as simple and natural as

    $stmt = $db->prepare($sql);
    $stmt->execute($data);
    
  2. Okay, you have such a whim of using mysqli. Then, as long as you are using a supported PHP version, you can use a splat or a three dot operator:

    $stmt = $db->prepare($sql);
    $types = str_repeat('s', count($data));
    $statement->bind_param($types, ...$data);
    $statement->execute();
    
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345