Page 1 sur 2

Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 14:08
par davlongin
Bonjour,

J'ai l'erreur suivante : PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in...

Je comprends pas pourquoi j'ai un problème avec mes variables de ma fonction ajouter() alors que dans la fonction prepare() et execute() j'ai le même nombre de variables avec une écriture identique.

Le code en question :
<?php
function ajouter($image, $nom, $prix, $desc){
        // Demander un accés à la connexion
        if(require("connexion.php")){
            $req = $access->prepare("INSERT INTO produits (image, nom, prix, description) VALUES ('$image', '$nom', $prix, '$desc')");
            $req->execute(array($image, $nom, $prix, $desc));
            //echo $req;
            var_dump($image, $nom, $prix, $desc);
            $req->closeCursor();
            // Permet de tout fermer
        }
    }
?>
Et voici ce que j'ai dans mon fichier connexion.php :
<?php
    try {
        $access = new pdo("mysql:localhost;dbaname=monoshop;charset=utf8", "root", "");

        $access->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

    } catch(Exception $e) {
        $e->getMessage();
    }
?>
Merci de me fournir votre aide si possible. Merci d'avance !

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 14:40
par or 1
alors que dans la fonction prepare() et execute() j'ai le même nombre de variables
non
une régle : cela n'arrivera jamais que php fasse une erreur en indiquant qu'il y a une erreur.
voir ce que dit la doc sur prepare et execute, ses exemples.

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 15:38
par davlongin
Justement même en lisant la doc et en prenant les exemples, rien ne m'aide forcément. Je suis un peu bloqué...

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 15:42
par or 1
on peut avoir un copier d'un exemple de la doc ?

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 15:46
par davlongin
PDOStatement::execute
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.1.0)

PDOStatement::execute — Exécute une requête préparée

Description ¶
public PDOStatement::execute(?array $params = null): bool
Exécute une requête préparée. Si la requête préparée inclut des marqueurs de positionnement, vous pouvez :

PDOStatement::bindParam() et/ou PDOStatement::bindValue() doit être appelé pour lier des variables ou des valeurs (respectivement) aux marqueurs de paramètres. Les variables liées passent leurs valeurs en entrée et reçoivent les valeurs de sortie, s'il y en a, de leurs marqueurs de positionnement respectifs

ou passer un tableau de valeurs de paramètres, uniquement en entrée

Liste de paramètres ¶
params
Un tableau de valeurs avec autant d'éléments qu'il y a de paramètres à associer dans la requête SQL qui sera exécutée. Toutes les valeurs sont traitées comme des constantes PDO::PARAM_STR.

Les valeurs multiples ne peuvent pas être liées à un seul paramètre; par exemple, il n'est pas autorisé de lier deux valeurs à un seul paramètre nommé dans une clause IN().

La liaison de plus de valeurs que spécifié n'est pas possible ; s'il y a plus de clés dans params que dans le code SQL utilisé pour PDO::prepare(), alors la requête préparée échouera et une erreur sera levée.

Valeurs de retour ¶
Cette fonction retourne true en cas de succès ou false si une erreur survient.

Exemples ¶
Exemple #1 Exécute une requête préparée avec des variables et valeurs liées
<?php
/* Exécute une requête préparée en liant des variables et valeurs */
$calories = 150;
$couleur = 'ver';
$sth = $dbh->prepare('SELECT nom, couleur, calories
    FROM fruit
    WHERE calories < :calories AND couleur LIKE :couleur');
$sth->bindParam('calories', $calories, PDO::PARAM_INT);
/* Les noms peuvent aussi être préfixés par des deux-points ":" (facultatif) */
$sth->bindValue(':colour', "%$colour%");
$sth->execute();
?>
Exemple #2 Exécute une requête préparée avec un tableau de valeurs nommées
<?php
/* Exécute une requête préparée en passant un tableau de valeurs */
$calories = 150;
$couleur = 'rouge';
$sth = $dbh->prepare('SELECT nom, couleur, calories
    FROM fruit
    WHERE calories < :calories AND couleur = :couleur');
$sth->execute(array('calories' => $calories, 'colour' => $colour));
/* Les clés du tableau peuvent aussi être préfixées par des deux-points ":" (facultatif) */
$sth->execute(array(':calories' => $calories, ':couleur' => $couleur));
?>
Exemple #3 Exécute une requête préparée avec un tableau de valeurs positionnels
<?php
/* Exécute une requête préparée en passant un tableau de valeurs */
$calories = 150;
$colour = 'rouge';
$sth = $dbh->prepare('SELECT nom, couleur, calories
    FROM fruit
    WHERE calories < ? AND couleur = ?');
$sth->execute(array($calories, $couleur));
?>
Exemple #4 Exécute une requête préparée avec des variables lié à un marqueur de positionnement
<?php
/* Exécute une requête préparée en liant des variables PHP */
$calories = 150;
$couleur = 'rouge';
$sth = $dbh->prepare('SELECT nom, couleur, calories
    FROM fruit
    WHERE calories < ? AND couleur = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT);
$sth->bindParam(2, $couleur, PDO::PARAM_STR, 12);
$sth->execute();
?>
Exemple #5 Exécute une requête préparée en utilisant un tableau pour les clauses IN
<?php
/* Exécute une commande préparée en utilisant un tableau de valeurs pour les clauses IN */
$params = array(1, 21, 63, 171);
/* Crée une chaîne pour les marqueurs */
$place_holders = implode(',', array_fill(0, count($params), '?'));

/*
    Ce morceau de code va préparer la requête avec assez de marqueurs pour chaque valeur
    du tableau $params. Les valeurs du tableau $params sont ensuite liées aux marqueurs
    de la requête préparée lorsque la requête est exécutée. Ce n'est pas la même chose
    que d'utiliser la méthode PDOStatement::bindParam() sachant qu'elle impose une
    référence vers les valeurs. La méthode PDOStatement::execute() ne fait que lier
    par la valeur.
*/
$sth = $dbh->prepare("SELECT id, name FROM contacts WHERE id IN ($place_holders)");
$sth->execute($params);
?>
PDO::prepare
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PHP 8,PECL pdo >= 0.1.0)

PDO::prepare — Prépare une requête à l'exécution et retourne un objet

Description ¶
public PDO::prepare(string $query, array $options = []): PDOStatement|false
Prépare une requête SQL à être exécutée par la méthode PDOStatement::execute(). Le modèle de déclaration peut contenir zéro ou plusieurs paramètres nommés (:nom) ou marqueurs (?) pour lesquels les valeurs réelles seront substituées lorsque la requête sera exécutée. L'utilisation à la fois des paramètres nommés ainsi que les marqueurs est impossible dans un modèle de déclaration ; seul l'un ou l'autre style de paramètre. Utilisez ces paramètres pour lier les entrées utilisateurs, ne les incluez pas directement dans la requête.

Vous devez inclure un marqueur avec un nom unique pour chaque valeur que vous souhaitez passer dans la requête lorsque vous appelez PDOStatement::execute(). Vous ne pouvez pas utiliser un marqueur avec deux noms identiques dans une requête préparée, à moins que le mode émulation ne soit actif.

Note:

Les marqueurs de paramètres peuvent représenter uniquement un littéral de données complet. Ni une partie de littéral, ni un mot clé, ni un identifiant, ni toute autre requête arbitraire ne peuvent être liés en utilisant les paramètres. Par exemple, vous ne pouvez associer plusieurs valeurs à un seul marqueur de nom entrant, dans la clause IN() d'une requête SQL.

Appeler PDO::prepare() et PDOStatement::execute() pour les requêtes qui doivent être exécutées plusieurs fois avec différentes valeurs de paramètres optimisent les performances de votre application en autorisant le pilote à négocier coté client et/ou serveur avec le cache des requêtes et les meta-informations. Deplus appeler PDO::prepare() et PDOStatement::execute() aident à prévenir les attaques par injection SQL en éliminant le besoin de protéger les paramètres manuellement.

PDO émule les requêtes préparées / les paramètres liés pour les pilotes qui ne le supportent pas nativement, et peut également réécrire les paramètres nommés ou les marqueurs en quelques choses de plus approprié, si le pilote supporte un style et pas l'autre.

Note: L'analyseur utilisé pour les déclarations préparés émulées et pour réécrire les paramètres nommés ou du style point d'intérogation supporte l'échappement antislash non standard pour les guillemets simple et double. Ceci signifie que des guillemets terminant qui sont précédés par un antislash ne seront pas reconnue comme tel, ce qui peut résulter dans une mauvaise détection des paramètres causant la déclaration préparer d'échouer lorsqu'elle est exécuté. Un contournement est de ne pas utiliser les requêtes émulées pour de telles requêtes SQL, et d'éviter de réécrite les paramètres en utilisant un style de paramètre qui est supporté nativement par le pilote.

À partir de PHP 7.4.0, les points d'interrogation peuvent être échappés en les dédoublant. Cela signifie que la chaîne ?? sera traduite en ? lors de l'envoi de la requête à la base de données.

Liste de paramètres ¶
query
Doit être un modèle de requête SQL valide pour le serveur de base de données ciblée.

options
Ce tableau contient une ou plusieurs paires clé=>valeur pour définir les valeurs des attributs pour l'objet PDOStatement que cette méthode retourne. Vous pouvez utiliser ceci pour définir la valeur PDO::ATTR_CURSOR à PDO::CURSOR_SCROLL pour demander un curseur scrollable. Quelques pilotes ont des options spécifiques qui peuvent être définies au moment de la préparation.

Valeurs de retour ¶
Si le serveur de base de données prépare avec succès cette requête, PDO::prepare() retourne un objet PDOStatement. Si le serveur de base de données ne réussit pas à préparer la requête, PDO::prepare() retourne false ou émet une exception PDOException (suivant le gestionnaire des erreurs).

Note:

L'émulation de requêtes préparées ne communique pas avec le serveur de base de données. Aussi, la fonction PDO::prepare() ne vérifie pas la requête.

Exemples ¶
Exemple #1 Modèle de déclaration SQL avec des paramètres nommés
<?php
/* Exécute une requête préparée en passant un tableau de valeurs */
$sql = 'SELECT nom, couleur, calories
    FROM fruit
WHERE calories < :calories AND couleur = :couleur';
$sth = $dbh->prepare($sql, [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);
$sth->execute(['calories' => 150, 'couleur' => 'red']);
$red = $sth->fetchAll();
/* Les clés du tableau peuvent être préfixées par des deux-points ":" également (facultatif) */
$sth->execute([':calories' => 175, ':couleur' => 'yellow']);
$yellow = $sth->fetchAll();
?>
Exemple #2 Modèle de déclaration SQL avec des marqueurs
<?php
/* Exécute une requête préparée en passant un tableau de valeurs */
$sth = $dbh->prepare('SELECT nom, couleur, calories
    FROM fruit
    WHERE calories < ? AND couleur = ?');
$sth->execute([150, 'rouge']);
$red = $sth->fetchAll();
$sth->execute([175, 'jaune']);
$yellow = $sth->fetchAll();
?>
Exemple #3 Modèle de déclaration SQL avec un point d'interrogation échappé
<?php
/* note: ceci n'est valable que pour les bases de données PostgreSQL */
$sth = $dbh->prepare('SELECT * FROM issues WHERE tag::jsonb ?? ?');
$sth->execute(['feature']);
$featureIssues = $sth->fetchAll();
$sth->execute(['performance']);
$performanceIssues = $sth->fetchAll();
?>

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 15:49
par or 1
on peut avoir un copier d'un exemple de la doc (et pas de la page de la doc entière) ?

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:02
par davlongin
Dsl, voici un exemple de la doc ( execute() )
<?php
/* Exécute une requête préparée en passant un tableau de valeurs */
$calories = 150;
$couleur = 'rouge';
$sth = $dbh->prepare('SELECT nom, couleur, calories
    FROM fruit
    WHERE calories < :calories AND couleur = :couleur');
$sth->execute(array('calories' => $calories, 'colour' => $colour));
/* Les clés du tableau peuvent aussi être préfixées par des deux-points ":" (facultatif) */
$sth->execute(array(':calories' => $calories, ':couleur' => $couleur));
?>

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:05
par or 1
que donne
echo "INSERT INTO produits (image, nom, prix, description) VALUES ('$image', '$nom', $prix, '$desc')";
echo "SELECT nom, couleur, calories FROM fruit WHERE calories < :calories AND couleur = :couleur";
?

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:20
par davlongin
En faisant l'echo, j'obtiens ceci :
INSERT INTO produits (image, nom, prix, description) VALUES ('https://image1.lacoste.com/dw/image/v2/ ... 213_24.jpg', 'Sac de luxe', 25, 'texteBlabla')

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:22
par or 1
quelle valeur va avoir le champ prix avec un tel résultat ?

SELECT nom, couleur, calories FROM fruit WHERE calories < :calories AND couleur = :couleur
quelle valeur va avoir le champ couleur du where ?

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:24
par davlongin
Mais l'exemple de la doc n'a pas de lien avec mon code, je vous ai juste donné un exemple landa. Et la valeur du prix saura 25 comme indiquée dans la requête SQL

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:29
par or 1
l'exemple de la doc montre comment faire un requête préparée. vous cherchez à faire une requête préparée et il faut faire une requête préparée dans ce cas, donc si, il y a un lien.

quelle valeur va avoir le champ prix avec un tel résultat ?
c'est bien 25

SELECT nom, couleur, calories FROM fruit WHERE calories < :calories AND couleur = :couleur
quelle valeur va avoir le champ couleur du where ?

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 16:35
par davlongin
La valeur qui sera rentré par l'utilisateur à l'aide du formulaire ou une valeur contenue dans une variable

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 17:15
par Spols
@or 1
Tu le fait tournée en bourrique ??

Regarde la manière dont tu insére tes paramètre dans ta requète préparé, et compare avec l'exemple de la doc.

Re: Fonction en php (Erreur au niveau du nombre de variables)

Posté : 09 janv. 2023, 17:41
par davlongin
C'est j'ai pu trouver mon erreur, je devais utiliser les marqueurs interrogatifs au lieu d'utiliser mes variables prédéfinis.

Voici la correction de mon code :
$req = $access->prepare("INSERT INTO monoshop.produits (image , nom, prix, description) VALUES (?, ?, ?, ?)");
            
$req->execute(array($image, $nom, $prix, $desc));
Merci pour votre aide.

Bonne soirée !