PHP and MYSQLi - Bind parameters using loop and st

2019-02-22 11:52发布

问题:

It will be easier to explain with the next code (It's wrong, by the way):

        $selectGenre_sql = 'SELECT genreID FROM genres WHERE dbGenre = ?';

        if ($stmt->prepare($selectGenre_sql)) {
        // bind the query parameters
        $stmt->bind_param('s', $genre);
        // bind the results to variables
        $stmt->bind_result($genres);
        // execute the query
        $stmt->execute();
        $genre = array();
            while ($stmt->fetch()) {
                $genre[] = $genres;
            }
        }

The code above gets the value from 'genreID' when 'dbGenre' is equal to '$genre'. And then store the results in an array. But i'ts not working. Why? I think because '$genre' is an array, so I need to loop trough it to get a different value from 'genreID' each time.

$genre is an enumerated array containing movie genres, for example:

[0] => Action [1] => Adventure [2] => Fantasy

I need to compare de value (like 'Action' for example)

The 'genres' table contains two columns: genreID (INT) and dbGenre (VARCHAR)

I just need each genreID (that is a number).... Lets say.. when dbGenre is equal to Action, then store the genreID in an array1, and then loop the $genre array to get the genreID for the next value and store it again in array1

How can I fix it?? I'm new to programming so please be as detailed as you can. Thanks!!

回答1:

You can't bind an array to an SQL parameter. You can use a parameter in SQL in place of a single literal value. Not a list of values, or an expression, or a column name or table name.

To solve the task in your case, you can use either of two solutions:

First solution: loop over $genre array, bind each value one at a time, and execute the SQL query for each value.

if ($stmt->prepare($selectGenre_sql)) {
  $genre = array();
  foreach ($gengre as $genreID) {
    $stmt->bind_param('s', $genreID);
    $stmt->execute();
    $stmt->bind_result($genres);
    while ($stmt->fetch()) {
      $genre[] = $genres;
    }
  }
}

Second solution: execute the query once, with multiple parameters, one for each value in the array. This requires some tricky code to build a variable number of ? placeholders in the SQL query, separated by commas.

$selectGenre_sql = 'SELECT genreID FROM genres WHERE dbGenre IN ('
 . join(',', array_fill(0, count($genre), '?')) . ')';

if ($stmt->prepare($selectGenre_sql)) {
  $genre = array();
  . . .

Also you need to get tricky calling bind_param() with a variable number of arguments based on the elements in your $genre array:

  . . .
  call_user_func_array( array($stmt, 'bind_param'), 
    array_unshift($genre, str_repeat('i', count($genre)));

  $stmt->execute();

  $stmt->bind_result($genres);

  while ($stmt->fetch()) {
    $genre[] = $genres;
  }
}

You might want to consider using PDO::mysql because it's easier to bind parameters from an array. The MySQLi interface is pretty awkward for this case.



回答2:

@ Bill Karwin

call_user_func_array won't pass the args by reference , it will pass the values so wont work! it will give you stmt->bind_param error

pdo its not a better solution ... u still have to do a workaround for that too

this should be edited in ur post :

if($stmt = ...same as yours) {
array_unshift($genre, str_repeat('i', count($genre)));
$temp = array();
foreach($genre as $key => $value) {
    $temp[$key] = &$genre[$key];
}
call_user_func_array(array($stmt, 'bind_param'), $temp);
etc...
}


回答3:

A few things.

  • Could it be is't because your overwriting the $genre var, try changeing it to $genreArray in the sedond case?
  • Make sure that the database is actually returning things (try it in phpMyAdmin or something similar)

  • Try processing like this:

.

 $genreId = -1;
 $stmt->bind_results($genreId);
 $stmt->execute();
 while($stmt->fetch()){
  $genreArray[] = $genreId;
 }