Bonjour à tous...

Je reviens avec mon PDO !
Je modifie actuellement toutes les pages de mon application Web pour remplacer la syntaxe classique par une POO...
J'arrive actuellement à enregistrer des données dans ma table, mais je ne parviens pas à faire la vérification que je faisais avant, à savoir : s'assurer que l'enregistrement d'un aliment depuis un formulaire n'est pas déjà présent dans la table (pour ne pas faire de doublon - plus tard, j'essaierai d'éviter les doublons depuis la saisie même du formulaire, mais pour ça il me faut de l'Ajax, et ça, c'est pas gagné !)

Voici mon code complet, si vous pouviez me dire où ça cloche et pourquoi ma page html générée reste désespérément vide sans même d'information sur l'erreur ?

PDO : C'est pas un CADO !

Merci d'avance pour votre aide !

<?php
header('Refresh: 4; URL= +aliment.php');

// Connexion à la base de données : 
include ('connexion.php');

// Le formulaire possède t-il un champ 'nom' ?
if (isset($_POST['nom'])) {
    // L'aliment est-il déja présent dans la base ? 
    // Formatage du nom de l'aliment :  
    $nom = strtoupper($_POST['nom']);

    // Requête comptage des aliments portant le même nom :
    $sql = "SELECT * FROM menu_aliments WHERE aliment_nom= '$nom'";
    $req = $bdd->exec($sql);
    //echo $req;
    $resultat = $req->fetchAll();

    if count($resultat) {     // L'aliment existe dans la base, on ne l'enregistre donc pas : 
        $message = 'L\'aliment '. $nom . ' fait déjà parti de la base de données, il n\'a donc pas été ajouté !';
    }

    else {     // L'aliment n'existe pas, on peut donc l'enregistrer :  

    // Libération du curseur : 
    $req -> closeCursor();

    // Récupération (et sécurisation ?) des données du formulaire : 

    $classe = $_POST['classe'];
    $unite = $_POST['unite'];
    $calorie = $_POST['calorie'];
    $rayon = $_POST['rayon'];
    $type = $_POST['type'];

    // Préparation de la requête d'insertion : 
    $req = $bdd->prepare('INSERT INTO menu_aliments (aliment_nom, aliment_classe, aliment_unite, aliment_calorie, aliment_rayon) VALUES (:nom, :classe, :unite, :calorie, :rayon)');

    // Exécution de la requête : 
    $req->execute(array(
        'nom' => $nom,
        'classe' => $classe,
        'unite' => $unite,
        'calorie' => $calorie,
        'rayon' => $rayon
    )) or die(print_r($req->errorInfo()));

    // Message d'information : 
    $message ='L\'aliment ' . '<strong>' . $nom . '</strong>' . ' a bien été enregistré dans la base...' . '<br />' .
    'Voici le détail :' . '<br />' . '<br />' .
    'Nom : ' . $nom . '<br />' .
    'Classe : ' . $classe . '<br />' .
    'Unité : ' . $unite . '<br />' .
    'Calories : ' . $calorie . '<br />' .
    'Rayon : ' . $rayon . '<br />' .
    'Type de plat : ' . $type. '<br />' . '<br />' .
    "Vous allez être redirigé à la page précédente...";
    }
}

else {     // Le champ 'nom' n'est pas renseigné : 
    $message =  "Un problème est survenu et votre aliment n'a pas été enregistré," . '<br />' . 
    "Vous allez être redirigé à la page précédente...";
}

?>

14 réponses


Inspirat
Réponse acceptée

D'accord, affiche la variable $count pour voir ce qu'elle retourne, sinon ça foncitonnera peut-être comme ça:

// A la place de "if($count){...}"
if($count > 0){
    // ....
}

Oui je comprend pas l'intérêt du header ici.
De plus je ne vois aucun affichage de la variable $message.

@Brandon-xprodeur :
Je ne sais pas ce que c'est un header location ?
Je veux juste faire une requête qui vérifie que l'aliment $nom n'est pas déjà
présent dans la table menu_aliments...D'ailleurs, la partie d'insertion fonctionne déjà,
ce qui ne fonctionne pas, c'est ce que j'ai rajouté et qui contrôle la présence (ou non)
de l'aliment...

@Couss :
1 - Le header me sert à indiquer la page vers laquelle retourner au bout de 4 secondes.
L'utilisateur a le temps de lire si l'aliment a été enregistré ou s'il est déjà présent
dans la table...sauf que la partie vérif ne fonctionne pas, d'ou mon post ici !

2 - La variable $message s'affiche dans le html en dessous du PHP, mais ce n'est pas
elle qui pose problème...
Voici qd même le code :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <!--[if lt IE 9]>
        <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
        <title>MENUS</title>
        <link rel="icon" href="favicon.ico " type="image/x-icon" />
        <link rel="shortcut icon" href="/images/favicon.ico " type="image/x-icon" />
        <link rel="stylesheet" type="text/css" href="css/style.css?<?php echo date('l jS \of F Y h:i:s A'); ?>" />
    </head>

    <body>
        <div class="header">
            <img src="../images/logo2.png" alt="Logo">
        </div><!--header-->

        <h4>PROGRAMME DE MENUS</h4>
        <p>
            Enregistrement de l'aliment
        </p>

        <a href="index.php">Accueil</a><br /><br />

        <?php

        echo $message;

        ?>

    </body>
</html>

Bonjour, pour commencer, j'aimerais te faire remarquer que la façon donc tu utilises la PDO ne te protège pas de l'injection dans le cas de ta première requête, je t'invite donc à toujours utiliser les requêtes préparés. De plus pourquoi vouloir sélectionner tous les éléments correspondent à la variable $nom, si théoriquement il n'y en a qu'un et un seul suffit pour dire qu'il existe déjà ? Puisque là MySQL va parcourir l'ensemble de ta table avant de retourner la réponse, ce qui est une perte de temps (même si la différence est presque inexistante sur une petite table) et dans la même optique, pourquoi sélectionner tous les éléments de la table lorsque tu vérifies s'il y a un doublon alors que le champ ID pourrait être suffisant (ça demande moins de temps).

Par suite pour ton problème de message d'erreur, c'est parce que tu ne l'affiche visiblement pas sur ta page, voici comment je procèderai:

<?php
    header('Refresh: 4; URL= +aliment.php');

    // Connexion à la base de données : 
    include ('connexion.php');

    // Le formulaire possède t-il un champ 'nom' ?
    if (isset($_POST['nom']) && !empty($_POST['nom'])) {

        // Formatage du nom de l'aliment : 
        $nom = strtoupper($_POST['nom']);

        $req = $bdd->prepare("SELECT id FROM menu_aliments WHERE aliment_nom = :nom");
        $req->execute(array('nom' => $nom));
        $count = $req->rowCount();

        if($count){
            $message = "L'aliment $nom fait déjà parti de la base de données, il n'a donc pas été ajouté !";
        } else {
            $req = bdd->prepare("INSERT INTO menu_aliments (aliment_nom, aliment_classe, aliment_unite, aliment_calorie, aliment_rayon) VALUES (:nom, :classe, :unite, :calorie, :rayon)");
            $req->execute(array(
                'classe' => $_POST['classe'],
                'unite' => $_POST['unite'],
                'calorie' => $_POST['calorie'],
                'rayon' => $_POST['rayon'],
                'type' => $_POST['type']
            ));

            $message = nl2br("L'aliment <strong>$nom</strong> a bien été enregistré dans la base de données.
            Voici le détail:

            Nom: $nom
            Classe: {$_POST['classe']}
            Unité: {$_POST['unite']}
            Calories: {$_POST['calorie']}
            Rayon: {$_POST['rayon']}
            Type de plat: {$_POST['type']}

            Vous allez être redirigé à la page précédente...");
        }
    } else {
        $message = nl2br("Un problème est survenu votre aliment n'a pas été enregistré.
        Vous allez être redirigé à la page précedente...");
    }

    if(isset($message)){ 
        echo $message; 
    }
?>

@Inspirat :

Merci pour ta réponse...

1 - Le fait d'utiliser $req = $bdd->prepare neutralise les eventuelles données JavaScript ou Sql d'un
utilisateur ? Avant j'utilisais htmlspecialchars... Maintenant, en suivant ce conseil cela devient inutile ?
Cela veut dire aussi que ma deuxième requête est bonne ?

2 - Je veux bien m'arrêter à la première "TOMATE" car dans la table aliment il ne peux y avoir
d'autre, sauf que je ne connais pas son id... L'utilisateur vient de valider un formulaire pour
ajouter un nouvel aliment à la table, c'est donc bien sur la variable $nom que je dois faire ma
recherche !

3 -Le message d'erreur, j'y répond 1 minute avt ton post... Je me suis mal exprimé, j'aurais dû
dire : Pourquoi ma page reste blanche, comme plantée ?

Il y a du mieux, je n'ai plus de page toute blanche, j'ai un message qui me dit que l'aliment est déjà dans la table
mais il me le dit tout le temps, même pour les nouveaux aliments !
je vais relire mon code...

En attendant :

  • Je remarque que tu n'utilises pas $req -> closeCursor(); pour remettre à zéro (?) $req....
  • Je ne connaissait pas nl2br, cela semble plus pratique que la concaténation dans mon cas.

Pour ce qui est de la requête, tu fais bien la recherche par rapport au nom, mais tu fais une sélection global de la ligne avec:

<?php

// Ta requête initiale retourne toutes les colonnes de la ligne correspondante
$req = $bdd->prepare("SELECT * FROM table WHERE nom = :nom");

// Cette requête retourne juste l'ID, ce qui offre un léger gain de temps (invisible sur une petite table, mais disons que c'est une habitude à prendre :D)
$req = $bdd->prepare("SELECT id FROM table WHERE nom = :nom");

?>

Bien sûr il faut adapter l'élément sélectionner à ta recherche, si tu a besoin de retourner d'autres informations, tu les ajoutes au SELECT, mais l'idée est de récupérer le minimum de valeur, le stricte nécessaire.
D'ailleurs je viens de remarquer que j'ai oublié quelque chose sur la première requête, la voici comme il faut:

// On limite la requête à la première occurence avec LIMIT 1
$req = $bdd->prepare("SELECT id FROM menu_aliments WHERE aliment_nom = :nom LIMIT 1");

if($count > 0){ ===> Un aliment déjà existant peut être enregitré une deuxième fois : Pas bon
$req = $bdd->prepare("SELECT id FROM menu_aliments WHERE aliment_nom = :nom LIMIT 1"); = = = > Plantage sans aucun message d'erreur !

J'suis couillon, ma colonne s'appelle aliment_id !

Ayé ça fonctionne !

En plus, grâce à toi, je viens de découvrir "WHERE nom = :nom"

Je ne savais pas comment mettre la variable dans ma requête
(des " ou des ' avec des \ suivis de . ! ! !)

Merci Inspirat

Tu as manifestement de grosses lacunes en php, je te conseillerais donc de revoir ta formation notamment au niveau de pdo ;)

Le "if($count > 0)" se traduit par si $count (qui représente le nombre de correspondance dans la base de données) est supérieur à 0 on affiche le message disant que l'enregistrement existe déjà

@SquallX : Tu as 100% raison, j'ai de grosses lacunes en php... En fait c'est pour ça que je suis ici. Si tout le monde savais tout
sur tout, les forums seraient plein de vide et Internet sans vie.

A 50 balais, je fais du code pour le plaisir, un programme de gestion d'aliments qui ne servira à rien au final, installé sur un
serveur local Debian 7, accessible depuis l'extérieur par un NAT et des redirections DNS, tout ça grâce à des infos trouvées
sur Internet et données par des gens désireux de partager leur savoir !

Partout on me dit de virer mes lignes classiques pour les remplacer par de la POO. C'est galère, mais je comprends petit à petit.
Je fais des efforts pour lire des livres, regarder des vidéos (de Grafikart entre autres car très pro) et quand je bloque
pendant plusieurs jours sur problème, j'appelle au secours. Quel bonheur d'avoir quelqu'un qui met le doigt sur
le ; oublié ou vous fait découvrir ce que le livre à passé...Le visage s'illumine quand l'étincelle jaillit !

A mon humble niveau j'essaie aussi d'aider les autres, quand je peux, dans d'autres domaines, car ça me fait plaisir
de savoir et de diffuser.

N'est-ce pas un peu le principe de base d'Internet ?

Ce n'était pas une critique rassures toi :)

Le soucis qu'on a bien souvent quand on commence à développer, c'est de vouloir aller trop vite et faire trop gros. Moi le premier ;)
C'est pour cela qu'il est bon de tester pleins de petits bouts de codes, ou de tenter de faire des choses simples pour commencer. Tu veux t'entraîner avec PDO ? Et bien commences par exemple par te remplir une base de données avec 2-3 tables contenant des infos différentes, et entraîne toi avec des requêtes à insérer, modifier, supprimer, créer, trier et récupérer des données dans de petits fichiers par exemple ;)