0

I have a similar problem like the author of this question:

MySQLI binding params using call_user_func_array

But before my question get duplicated tag, the solution didn't worked out for me.

That actually is my code:

    // in classfoodao.php
function updateClassfoo(Classfoo $classfoo){   
  $values = array();
  global $conn,$f;
  $pattern = "";
  /* updateFields get all defined attributes in classfoo object and then write in the $sql string
  *  A prepared statement only for the not null attribs,
  *  and also put the attribs in the same order in the $values array.
  * The same are done for the $pattern string.
  * $values and $pattern are passed by reference.
  */
  $sql = $classfoo->updateFields($values, $pattern); 
  if (!empty($values) && !empty($pattern)) {
    $stmt = $conn->prepare($sql);
    $temp  = array($pattern);
    for ($i = 0, $count = count($values); $i < $count; $i++) {
      $addr = &$values[$i];
      array_push($temp, $addr);
    }
    call_user_func_array(array($stmt, "bind_param"), $temp);
  } else {
    return true;
  }
}

And I still getting this Warning:

PHP Warning:  Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given

Following with the error:

Execute failed on update: (2031) No data supplied for parameters in prepared statement

I'm not using any framework for PHP, how can I create an Array of references to solve this problem?

1 Answers1

0

I still get the feeling we do not have the whole picture here, however I think there is enough to formulate a sufficient answer.

It sounds like you want a function that takes a mysqli_stmt string and an array as it's 3 parameters and returns a parameterized SQL statement. In code your method signature would look like

/**
* Builds a parameterized Sql query from the provided statement, data type pattern and params array.
*
* @param string $stmt    The query string to build a parameterized statement from
* @param string $pattern The data type pattern for the parameters i.e. sssd for 3 strings and an interger.
* @param array  $params  A sequential array of the parameters to bind to the statement.
*
* @return mysqli_stmt The parameter bound sql statement ready to be executed.
*/
public function bind(string $stmt, string $pattern, array $params) : mysqli_stmt

You would call such a method as such

$stmt = bind(
    'INSERT INTO myTable (str_field, str_field_2, int_field) VALUES (?, ?, ?)',
    'ssd',
    ['val1', 'val2', 1337]
);
$result = $stmt->execute();

The implementation should be as trivial as this

public function bind(string $stmt, string $pattern, array $params) : mysqli_stmt {
    $mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');
    $preparedStmt = $mysqli->prepare($stmt);
    $preparedStmt->bind_param($pattern, ...$params);
    return $preparedStmt;
}

I of course would suggest you use dependency injection rather than creating a new mysqli object every time the function is called and you should do some error checking in regards to the $pattern and $param counts. There's still a lot I can't see but I hope this gets you on your way.

HopAlongPolly
  • 1,347
  • 1
  • 20
  • 48
  • It's a good approach, but it does not fit for me, because I need a function that works in a dynamic environment of what fields to update. For now I just maked a uggly 'switch case', but I'm fully hoping that somebody can help me with my problem. Btw: Thanks for the support so far. – Mateus S. Vasconcelos Sep 07 '17 at 23:37
  • Can you provide sample inputs and outputs to demonstrate the desired behaviour? – HopAlongPolly Sep 08 '17 at 12:49