2014-04-21 2 views
0

Je reçois l'erreur « SQLSTATE [HY093]: numéro de paramètre non valide: nombre de variables liées ne correspond pas à nombre de jetons » lorsque je tente d'exécuter la fonction ci-dessous:PDOException jeté en PHP

public function find_products($string = '', $fields = array(), $sort_by = '', $sort_dir = 'ASC') { 

    $fields = empty($fields) ? '*' : ('' . implode(',', $fields) . '?'); 
    $bindings = array('%' . $string . '%','%' . $string . '%','%' . $string . '%'); 
    $and_where_checks = array('series','material'); 
    $AND = ''; 

    // Loop through the POST variables to see what is safe to play with 
    $allowed = array(); 
    foreach ($and_where_checks as $awc) 
     if (! empty($_POST[$awc])) 
      $allowed = $awc; 

    if (! empty($allowed)) { 
     $tmp = array(); 
     foreach ($allowed as $v) 
      $tmp = '' . $v . ' IN (' . str_pad('', count($v) * 2 - 1, '?,') . ')'; 

     $AND = 'AND (' . implode(' AND ', $tmp) . ') '; 

     foreach ($allowed as $k) 
      foreach ($_POST[$k] as $v) 
       $bindings = $v; 
    } 

    $query = 
     "SELECT " . $fields . " FROM " . $this->product_table . " " . 
     "WHERE (" . $this->primary_key . " LIKE ? " . 
     $AND . 
     "ORDER BY " . $sort_by . " " . $sort_dir; 

    $sth = $this->$dbh->prepare($query); 

    $sth->execute($bindings); 

    return $sth->fetchAll(PDO::FETCH_ASSOC); 
} 

Les variables $ POST [$ awc] sont remplies par des cases à cocher sur cette page http://ladd-dev.bitstormweb.com/products/interactive-product-finder/. Lorsque je choisis un des groupes de cases à cocher (par exemple, 1 série et 1 article), les résultats sont corrects, mais lorsque je choisis plusieurs boîtes dans le même groupe, j'obtiens l'exception PDOException.

Est-ce que quelqu'un sait pourquoi? J'apprends toujours ce code donc toute aide serait appréciée!

Répondre

0

Dans votre requête, vous avez seulement une variable d'être lié (le?):

$query = 
    "SELECT " . $fields . " FROM " . $this->product_table . " " . 
    "WHERE (" . $this->primary_key . " LIKE ? " . 
    $AND . 
    "ORDER BY " . $sort_by . " " . $sort_dir; 

Ici, vous devez être soit en liant 0 ou lier plus de 1. Vérifiez le nombre de valeurs sont dans les liaisons de $ .

$sth = $this->$dbh->prepare($query); 
$sth->execute($bindings); 

Vous pouvez vérifier combien de valeurs sont dans les liaisons de $ en utilisant print_r($bindings);

Mise à jour: Sans savoir ce que votre entrée est, votre code semble utiliser les liaisons $ deux fois. Il est situé en haut avec 3 valeurs qui sont la même chose: $bindings = array('%' . $string . '%','%' . $string . '%','%' . $string . '%'); puis au fond vous avez un foreach où vous n'utilisez pas un tableau du tout:

foreach ($_POST[$k] as $v) 
      $bindings = $v; 
+0

Merci pour l'aide. Une fois que j'ai réussi à tout imprimer correctement pour le débogage, voici ce que j'obtiens: Pour $ bindings: 'Array ([0] => %% [1] => %% [2] =>% % [3] => EEC [4] => Plastique) ' Pour $ requête: 'SELECT' numéro_particle', 'photo_a' FROM' products' O WH ('partie_number' LIKE? OU' series' LIKE? OR 'matériel' LIKE?) ET (' série' IN (?) ET 'material' IN (?)) ORDER BY' numéro_particle' ASC' Je ne suis pas sûr si le? remplissez correctement. – user3557469

+0

Y a-t-il une raison pour laquelle vous utilisez WHERE IN pour la série et le matériel? Si ce ne sont que des variables, alors il semble plus logique d'utiliser 'series =? ET matériau =? '. Vous pouvez également voir à partir de votre tableau que les goûts ne sont pas remplis correctement, %%. Sauf si tu le veux comme ça. Testez la requête indépendamment en utilisant des valeurs prédéfinies, puis essayez d'utiliser les variables préparées avec. – Devon

+0

Merci pour l'aide Devon. J'ai compris que le coupable était que peu importe les entrées que j'utilisais, je ne construisais IN (?) Avec une valeur de tableau. J'ai donc ajusté le tableau $ tmp à remplir en fonction du nombre de cases cochées (à partir de l'entrée d'origine). '$ tmp = array(); $ c = compte ($ autorisé); // Nombre de variables avec contenu $ i = 0; // Lancement du placement de matrice \t \t \t foreach ($ autorisé sous $ v) { $ tmp [] = "". $ v. "IN (". Str_pad ('', count ($ _ POST [$ autorisé [$ i]]) * 2 - 1, '?,'). ")"; $ i ++; } ' – user3557469