Search code examples
phpmysqlprepared-statement

Fatal error: Uncaught ArgumentCountError: The number of elements in the type definition string must match the number of bind variables


I'm experiencing this error while I'm doing a prepared statement. But I counted all the variables a lot of time, and I was unable to find the error. The querystring in this case is: receipts.php?type=1|11|12|15

below the code:

$pag = 1; //page initialising

if ( isset( $_GET[ 'pag' ] ) ) {
  $pag = $_GET[ 'pag' ]; 
}
$resultsForPage = 20;
$startRecord = $pag * $resultsForPage - $resultsForPage;

$type = explode( "|", $_GET[ "type" ] ); //explode all the types in an array

$where = ' WHERE R.TipoRicetta = ? '; //initialize the where clause for the first item
$paramType = 'i';
$paramValue = $type[ 0 ];

//adding the other types
for ( $i = 1; $i < count( $type ); $i++ ) {
  $paramType .= 'i';
  $paramValue .= ',' . $type[ $i ];
  $where .= 'OR R.TipoRicetta = ? ';

}
    
    
$query = 'SELECT R.*, F.urlFoto, D.descrizione AS diff FROM ricette R
INNER JOIN ricFoto RF ON RF.idRicetta = R.IDContenuto
INNER JOIN foto F ON F.idFoto = RF.idFoto
INNER JOIN Tb_Difficolta D ON R.Difficolta = D.IDDifficolta' . $where . 'LIMIT ' . $startRecord . ',' . $resultsForPage;

the following is the query created by this code:

SELECT R.*, F.urlFoto, D.descrizione AS diff FROM ricette R INNER JOIN ricFoto RF ON RF.idRicetta = R.IDContenuto INNER JOIN foto F ON F.idFoto = RF.idFoto INNER JOIN Tb_Difficolta D ON R.Difficolta = D.IDDifficolta WHERE R.TipoRicetta = ? OR R.TipoRicetta = ? OR R.TipoRicetta = ? OR R.TipoRicetta = ? LIMIT 0,20

Printed on screen

$paramType value: iiii

$paramValue: 1,11,12,15

So:

  • 4 where clauses
  • 4 param types
  • 4 param values

what the hell I'm doing wrong?


Solution

  • You need to pass the bound parameters as separate values. You can build up an array and use a splatted array to pass the values in:

    $paramValue = [$type[ 0 ]];
    
    //adding the other types
    for ( $i = 1; $i < count( $type ); $i++ ) {
      $paramType .= 'i';
      $paramValue[] = $type[ $i ];
      $where .= 'OR R.TipoRicetta = ? ';
    
    }
    
    .....
    
    $stmt->bind_param($paramType, ...$paramValue);