Bonjour à tous,
Je ne trouve pas (ou cherche mal) sur Internet la syntaxe qui
permettrai de mettre à jour le champ 'prix' d'une table 'tarifs'
et ce, dans plusieurs enregistrements, tout en utilisant PDO bien sûr.
Au départ j'ai un tout bête formulaire qui affiche des noms de
chambres (non modifiables) avec chacune une zone de saisie
préremplie du prix de cette chambre (en provenance de ma bdd)

  • Faut-il utiliser while ?
    En fait, je ne visualise pas comment préparer ma requete, ni comment tourner ma mise à jour.

Voila déjà mon formulaire qui fonctionne :

<?php
include ('connexion.php');
// Requête : 
$sql = 'SELECT * FROM tarifs';

// Exécution :
$req = $DB->query($sql);

// Récupération des données
while ($data=$req->fetch(PDO::FETCH_OBJ)) { ?>
     <tr>
          <td><?php echo $data->chambre ;?></td>
          <td><input name="<?php echo $donnees['id_chambre'] ;?>" value="<?php echo $data->prix ;?>" /> </td>
     </tr>
<?php
}                        
?>

Merci d'avance pour une petite piste...

30 réponses


Carouge10
Réponse acceptée

La requête permet de récupérer l'id de chaque chambre pour faire la modification du prix
tarif :

<article><!-- Contenu textuel de la page -->
    <h1>TARIFS DES CHAMBRES</h1>
    <form method="post" action="modif_tarif.php">
        <table>
            <caption>Chambres présentes dans la base : </caption>
            <thead> <!-- En-tête du tableau -->
                <tr>                        
                    <th>Désignation</th>
                    <th>Prix TTC</th>
                </tr>
            </thead>
            <tbody> <!-- Corps du tableau -->
                <?php
                // Récupération des données
                while ($data=$req->fetch(PDO::FETCH_OBJ)) { ?>
                     <tr>
                          <td><?= $data->chambre ;?></td>
                          <td><input name="prix_chambre_<?= $data->id_chambre ;?>" value="<?= $data->prix ;?>" /> </td>
                     </tr>
                <?php
                }
                ?>
            </tbody>                            
        </table>
        <input type="submit" value="Valider">
        <input type="reset" value="Ré initialiser" />
    </form>                        

</article>

post_tarif

<?php
// Vérification droit accès : 
session_start();
if (!isset($_SESSION['login'])) {
    header ('Location: index.php');
    exit();
}

// Vérification durée session : 
if (time()-$_SESSION['derniereaction'] > 900) {
  // la session a expiré
    session_unset();
    session_destroy();
    header('Location: index.php');
    exit();
}
else {
    // La session est toujours en cours : 
    $_SESSION['derniereaction'] = time(); // on relance
    include ('connexion.php');

    // Requête : Permet de récupérer l'id des chambres pour modifier leur prix
    $sql = 'SELECT id_chambre FROM tarifs';

    // Exécution :
    $req = $DB->query($sql);

    while ($data=$req->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');
        $prix_chambre = "prix_chambre_".$data->id_chambre;
        $req->execute(array($_POST[$prix_chambre], $data->id_chambre));
    }
}
?>
Carouge10
Réponse acceptée

Je pense à un conflit entre les variables car une à la même nom.

// Requête : Permet de récupérer l'id des chambres pour modifier leur prix
    $sql = 'SELECT id_chambre FROM tarifs';

    // Exécution :
    $req = $DB->query($sql);

// Préparation de la requête pour modifier le prix des chambres
$req_update = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');

    while ($data=$req->fetch(PDO::FETCH_OBJ)) {
        $prix_chambre = "prix_chambre_".$data->id_chambre;
        $req_update->execute(array($_POST[$prix_chambre], $data->id_chambre));
    }

Bonjour,

Quelle est le point commun entre le nouveau prix et les chambres ? (une référence, un prix commun...)

(Merci Carouge10)

En fait, chaque chambre d'un gîte à son propre prix.
L'utilisateur doit pouvoir modifier en une seule fois, à l'aide
d'un formulaire (input), un ou plusieurs prix.
Les prix affichés qui n'auront pas été modifié seront ré-
enregistrés tels quels, les modifiés dans le formulaire
le seront dans la bdd...

S'il n'y a pas 10 000 chambres, un while sera suffisant.
Pour plus de simplicité, faite une mise à jour de tous les prix du formulaire, cela vous évitera de faire des comparaisons.
Le gain de temps sera quasi nul.

C'est justement la structure du while que je n'arrive pas à tourner en PDO,
notamment comment échaper les ' ou les " car je dois certainenement
reprendre des variables $_POST...

Il y a 4 chambres ! ! ! j'aurai plus vite fait de les modifier à la main dans la bdd,
mais le site final n'est pas pour moi !

UPDATE `tarifs` SET `prix`="$_POST['prix_chambre_xx']" WHERE `id`= $_POST['id_chambre']

pour échapper les ' et les ", utiliser :

$ma_var = $DB->quote($ma_var);

Merci,

J'adapte mes $_POST,
Mais est-comme ça la syntaxe de While ?:

// Requête : 
while ($data=$sql->fetch(PDO::FETCH_OBJ)) {
        $sql='UPDATE `tarifs` SET `prix`="$_POST['prix']" WHERE `id`= $_POST['id_chambre']';       
 }

Sauf que Sublime Texte m'affiche plein de rouge sur 'prix' et 'id_chambre'
Il doit y avoir une erreur de syntaxe quelque part !

Edit : Parse error: syntax error, unexpected 'prix' (T_STRING) in modif_tarif.php on line 24

Avec cette syntaxe, vous mettez le même prix pour toute les chambres. Est-ce c'est ce que vous souhaitez faire ?

// Requête : 
while ($data=$sql->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id`= ?');
        $req->execute(array($_POST['prix'], $_POST['id_chambre']);
 }

Non, chaque chambre a son propre prix...
J'ai corrigé la variable id par id_chambre et ajouté une ) manquante à la deuxième ligne :

// Requête : 
    while ($data=$sql->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');
        $req->execute(array($_POST['prix'], $_POST['id_chambre']));
    }

Mais j'ai toujours une erreur :
Fatal error: Call to a member function fetch() on a non-object in modif_tarif.php on line 23

Punaise, c'est compliqué !

EDIT : Idem pour : while ($data=$sql->fetch()) {

1/ Il faut que le prix du formulaire soit unique alors que la il est globale ==> $_POST['prix_chambre_xx] où xx correspodrait à l'id de la chambre
2/ ça ne serait par $req à la place de $sql ? Si non, puis-je avoir le code juste avant la boucle.

Pour un formulaire plus clair, je vous conseil ceci :

<?php
include ('connexion.php');
// Requête : 
$sql = 'SELECT * FROM tarifs';

// Exécution :
$req = $DB->query($sql);

// Récupération des données
while ($data=$req->fetch(PDO::FETCH_OBJ)) { ?>
     <tr>
          <td><?php echo $data->chambre ;?></td>
          <td><input name="prix_chambre_<?php echo $donnees['id_chambre'] ;?>" value="<?php echo $data->prix ;?>" /> </td>
     </tr>
<?php
}                        
?>

Et lors du traitement la boucle suivante sera mieux adapté :

// Requête : 
    while ($data=$sql->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');
        $prix_chambre = "prix_chambre_".$_POST['id_chambre'];
        $req->execute(array($_POST[$prix_chambre], $_POST['id_chambre']));
    }

Effectivement une erreur entre $sql et $req qui malheureusement ne change pas Fatal error...
Avant la boucle, je n'ai rien à part un contrôle de cession (accès + durée d'ouverture)

else {
    // La session est toujours en cours : 
    $_SESSION['derniereaction'] = time(); // on relance
    include ('connexion.php');

    // Requête : 
    while ($data=$req->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');
        $req->execute(array($_POST['prix'], $_POST['id_chambre']));
    }
}

$sql correspond à un résultat sur une requête et là, je ne vois aucune requête.

En fait, ça ne marche pas car je ne comprends pas comment structurer
la requete et la boucle... J'essaie de me mettre à PDO car partout où je
poste on me le conseille mais la syntaxe me semble bien plus complexe
et surtout je ne trouve ni doc claire ni exemple concret pour un truc
finalement très simple !
Le tuto vidéo de Grafikart sur PDO ainsi que mon livre PHP & MySql de
Mathieu Nebra n'expliquent qu'une mise à jour d'UN enregistrement avec
UPDATE, mais rien avec while et des variables de formulaire $_POST...
Je ne trouve pas non plus sur Internet (et c'est pas faute de chercher)
d'explications sur quand mettre dans une requete un ` ou un ' ou un " ou
un \' etc...
Je me guide avec les couleurs d'erreur de Sublime Texte !
Si à ce propos quelqu'un avait un lien pour expliquer clairement, ce
serait sympa...

Je reprends

  • un formulaire
    
    <?php
    include ('connexion.php');
    // Requête : 
    $sql = 'SELECT * FROM tarifs';

// Exécution :
$req = $DB->query($sql);

// Récupération des données
while ($data=$req->fetch(PDO::FETCH_OBJ)) { ?>
<tr>
<td><?= $data->chambre ;?></td>
<td><input name="prixchambre<?= $donnees['id_chambre'] ;?>" value="<?= $data->prix ;?>" /> </td>
</tr>
<?php
}
?>


- une page post traitement

<?php
include ('connexion.php');
// Requête :
$sql = 'SELECT * FROM tarifs';

// Exécution :
$req = $DB->query($sql);

// Récupération des données
while ($data=$req->fetch(PDO::FETCH_OBJ)) {
$req = $DB->prepare('UPDATE tarifs SET prix= ? WHERE id_chambre= ?');
$prix_chambre = "prixchambre".$_POST['id_chambre'];
$req->execute(array($_POST[$prix_chambre], $_POST['id_chambre']));
}
?>



Ne fonctionne pas ?
Vous avez bien mis les balises < form et </ form> ?

En effet, j'ai commis une erreur.
J'ai fais un select, mais je ne l'ai pas utiliser.
Celui-ci permet de chercher le bon $_POST;

$prix_chambre = "prix_chambre_".$data->id_chambre;
 $req->execute(array($_POST[$prix_chambre], $_data->id_chambre));

Et d'ailleurs le formulaire doit être faux lui aussi :

  • Vérifier dans l'inspecteur s'il y a bien name="prix_chambre_1" dans un des input de prix
    Sinon modifier ainsi
    <td><input name="prix_chambre_<?= data->id_chambre ;?>" value="<?= $data->prix ;?>" /> </td>

Merci pour cette aide...bien que je ne comprenne pas ce qu'un
$sql = 'SELECT * FROM tarifs'; vient faire dans le fichier de traitement...(passons).
En tout cas je n'ai plus de message d'erreur, mais les prix modifiés ne sont
pas enregistrés dans la bdd...

Voici mon code complet :

tarifs.php

<article><!-- Contenu textuel de la page -->
            <h1>TARIFS DES CHAMBRES</h1>
            <form method="post" action="modif_tarif.php">
                <table>
                    <caption>Chambres présentes dans la base : </caption>
                    <thead> <!-- En-tête du tableau -->
                        <tr>                        
                            <th>Désignation</th>
                            <th>Prix TTC</th>
                        </tr>
                    </thead>
                    <tbody> <!-- Corps du tableau -->
                        <?php
                        // Récupération des données
                        while ($data=$req->fetch(PDO::FETCH_OBJ)) { ?>
                             <tr>
                                  <td><?= $data->chambre ;?></td>
                                  <td><input name="prix_chambre_<?= $donnees['id_chambre'] ;?>" value="<?= $data->prix ;?>" /> </td>
                             </tr>
                        <?php
                        }                           
                        ?>
                    </tbody>                            
                </table>
                <input type="submit" value="Valider">
                <input type="reset" value="Ré initialiser" />
            </form>                        

        </article>

modif_tarif.php

<?php
// Vérification droit accès : 
session_start();
if (!isset($_SESSION['login'])) {
    header ('Location: index.php');
    exit();
}

// Vérification durée session : 
if (time()-$_SESSION['derniereaction'] > 900) {
  // la session a expiré
    session_unset();
    session_destroy();
    header('Location: index.php');
    exit();
}
else {
    // La session est toujours en cours : 
    $_SESSION['derniereaction'] = time(); // on relance
    include ('connexion.php');

    // Requête : 
    $sql = 'SELECT * FROM tarifs';

    // Exécution :
    $req = $DB->query($sql);

    while ($data=$req->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');
        $prix_chambre = "prix_chambre_".$_POST['id_chambre'];
        $req->execute(array($_POST[$prix_chambre], $_POST['id_chambre']));
    }
}
?>

(J'ai un problème avec mon Firefox/Linux Mint : impossible de poster 2 pages de code sur le même message

  • pas de rafraichissement même en faisant F5 => je ne voyais pas ta réponse !)

T'es un chef ! ! !
Ca fonctionne !

Je te remercie mille fois,
Je vais décortiquer ton code pour comprendre comment PDO est structuré.

Vraiment tu m'enlèves une épine du pied, je ne voyais pas comment m'en sortir !
(pas simple quand même pour quelque chose qui finalement, à l'écran ne semble
pas compliqué !)

Je vous en prie. Content que cela fonctionne.

Crié victoire trop vite...
Ca ne fonctionne que pour la première chambre
:-(

Quand vous inspectez votre formulaire, vous avez bien le name des input qui change ? (prix_chambre_1, prix_chambre_2...) ?
En haut de post_tarif, fait ceci et afficher le résultat ici :

var_dump($_POST); die("fin affichage $_POST");

Le formulaire semble bien s'afficher pourtant, voici le html généré :

<tbody> <!-- Corps du tableau -->
     <tr>
          <td>Chambre 1</td>
          <td><input name="prix_chambre_1" value="125.00" /> </td>
     </tr>
     <tr>
          <td>Chambre 2</td>
          <td><input name="prix_chambre_2" value="102.00" /> </td>
     </tr>
     <tr>
          <td>Chambre 3</td>
          <td><input name="prix_chambre_3" value="103.00" /> </td>
     </tr>
     <tr>
          <td>Chambre 4</td>
          <td><input name="prix_chambre_4" value="144.00" /> </td>
     </tr>
     <tr>
          <td>Chambre 5</td>
          <td><input name="prix_chambre_5" value="125.00" /> </td>
     </tr>
</tbody>               

et la page modif donne ça : (je viens de changer le tarif de la chambre 2)
array(5) { ["prix_chambre_1"]=> string(6) "125.00" ["prix_chambre_2"]=> string(2) "20" ["prix_chambre_3"]=> string(6) "103.00" ["prix_chambre_4"]=> string(6) "144.00" ["prix_chambre_5"]=> string(6) "125.00" } fin affichage Array

donc les infos sont bien passées !

modif_tarif.php :

// Requête : Permet de récupérer l'id des chambres pour modifier leur prix
    $sql = 'SELECT id_chambre FROM tarifs';

    // Exécution :
    $req = $DB->query($sql);

    while ($data=$req->fetch(PDO::FETCH_OBJ)) {
        $req = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');
        $prix_chambre = "prix_chambre_".$data->id_chambre;
        $req->execute(array($_POST[$prix_chambre], $data->id_chambre));
    }

Je te remercie Carouge10, c'etait bien ça : un même nom pour deux
requête différentes... Tout fonctionne parfaitement maintenant, grâce
à toi !

Si je n'abuse pas trop, quand tu auras 5 minutes pourrais tu m'expliquer
le fonctionnement de ce code ?

Voila ce que moi je comprends :
La première requête récupère dans la table 'tarifs' les numéros des enregistrements
de chaque chambre (différent de l'index primaire id)... Si un jour, je supprime la chambre
4 $req va récupérer 1, 2, 3, 5

La deuxième requête va mettre à jour le champs prix de la table tarifs à l'aide
d'une valeur inconnue (prix= ?) tant qu'on est pas entré dans la boucle while
à condition que le numéro de la chambre soit égal à une valeur inconnue
(id_chambre= ?) tant qu'on est pas entré dans la boucle while...

La boucle while reprend les n° des chambres de $req...
Après c'est moins clair !
On affecte une valeur à la variable $prix_chambre puis à partir de ->id_chambre; je
suis largué ! Le recours à un array aussi est obscure ...

Je vais essayer d'explicer clairement le focntionnement

// Requête : Permet de récupérer l'id des chambres pour modifier leur prix
    $sql = 'SELECT id_chambre FROM tarifs';

    // Exécution :
    $req = $DB->query($sql);

// Préparation de la requête avec des marqueurs (?) pour modifier le prix des chambres
$req_update = $DB->prepare('UPDATE `tarifs` SET `prix`= ? WHERE `id_chambre`= ?');

// Tant que nous avons des chambres...
    while ($data=$req->fetch(PDO::FETCH_OBJ)) {
        // Création d'une variable contenant le nom de l'input où contenu le prix en fonction de l'id de la chambre
        $prix_chambre = "prix_chambre_".$data->id_chambre;

        // Exécution de la requête UPDATE et remplaçant dans l'ordre les marqueurs
        // Le 1er marqueur (?) correspont au prix donc à $_POST[$prix_chambre], le 2ème correpond à l'id de la chambre
        $req_update->execute(array($_POST[$prix_chambre], $data->id_chambre));
    }

Une petite lecture de la page suivante concernant la méthode prepare de PDO : PDO prepare

Je te remercie pour ces explications très claires et du temps que tu as bien voulu me
consacrer...Cette partie de PDO devient plus limpide et je risque d'avoir souvent besoin
de cette structure de code pour afficher des données en quantité sur une page et la
possibilité d'en modifier que certaines !

J'ai omis sur chaque page les closeCursor(); ?
A ce propos, cette fonction s'applique t-elle à la $sql ou à $req car mon bouquin construit
ces requêtes comme ça ; $reponse=$bdd->query('REQUETE'); et applique le closeCursor sur
$reponse...

Edit : J'ai eu ma réponse avec un fatal error, c'est donc sur $req que j'ai placé mon
closeCursor();

Tout est nickel maintenant...
Merci encore Carouge10 ! ! !