web-dev-qa-db-fra.com

PHP PDOException: "SQLSTATE [HY093]: Numéro de paramètre non valide"

J'obtiens l'erreur "SQLSTATE [HY093]: Numéro de paramètre non valide" lorsque j'essaie d'exécuter la fonction ci-dessous:

function add_persist($db, $user_id) {
    $hash = md5("per11".$user_id."sist11".time());
    $future = time()+(60*60*24*14);
    $sql = "INSERT INTO persist (user_id, hash, expire) VALUES (:user_id, :hash, :expire) ON DUPLICATE KEY UPDATE hash=:hash";
    $stm = $db->prepare($sql);
    $stm->execute(array(":user_id" => $user_id, ":hash" => $hash, ":expire" => $future));
    return $hash;
}

J'ai l'impression que c'est quelque chose de simple que je n'attrape pas. Des idées?

24
vijrox

Essayer:

$sql = "INSERT INTO persist (user_id, hash, expire) VALUES (:user_id, :hash, :expire) ON DUPLICATE KEY UPDATE hash=:hash2";

et

$stm->execute(array(":user_id" => $user_id, ":hash" => $hash, ":expire" => $future, ":hash2" => $hash));

Extrait de la documentation ( http://php.net/manual/en/pdo.prepare.php ):

Vous devez inclure un marqueur de paramètre unique pour chaque valeur que vous souhaitez transmettre à l'instruction lorsque vous appelez PDOStatement :: execute (). Vous ne pouvez pas utiliser deux fois un marqueur de paramètre nommé du même nom dans une instruction préparée. Vous ne pouvez pas lier plusieurs valeurs à un seul paramètre nommé dans, par exemple, la clause IN () d'une instruction SQL.

39
vee

Il s'agit d'une limitation à l'utilisation de PDO. PDO reconnaît simplement le nombre de paramètres dans la requête et l'exécution et renvoie une erreur sur toute incompatibilité. Si vous devez utiliser la répétition de paramètres dans vos requêtes, vous devez vous y prendre en utilisant une solution de contournement

$sql = "insert into persist(user_id, hash, expire) values
    (:user_id, :hash, :value) on duplicate key update
    hash = :hash2";
$stm->execute(array(':user_id' => $user_id, ':hash' => $hash, ':hash2' => $hash,
    ':expire' => $expire));

Vous pouvez vous y référer pour une solution de contournement plus élaborée - https://stackoverflow.com/a/7604080/1957346

15
Achrome

Je sais que c'est une vieille question, mais je pense qu'il vaut la peine de noter qu'une solution plus appropriée serait d'éviter les solutions de contournement maladroites dans PHP en exploitant SQL de manière appropriée:

INSERT INTO `persist` (`user_id`, `hash`, `expire`)
VALUES (:user_id, :hash, :expire)
ON DUPLICATE KEY UPDATE `hash`=VALUES(`hash`)

De cette façon, vous n'avez besoin d'envoyer la valeur qu'une seule fois.

4
Duncan