IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

[PHP] Vérifications formulaire


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 6
    Par défaut [PHP] Vérifications formulaire
    Bonjour à tous.

    Développeur web en formation, je me retrouve face à un problème que je n'arrive pas à résoudre depuis 2 jours (et malgré de nombreuses recherches).

    J'ai le formulaire suivant (voir code ci-dessous) et je dois vérifier en php que le code postal soit correct et que les champs "prix" et "surface" ne contiennent que des entiers. J'ai essayé de nombreuses solutions mais rien ne fonctionne (même pas la regex du code postal qui laissait passer les lettres).

    Je me retrouve donc avec une page blanche (car cela m'a agacé et que j'ai tout effacé sans rien enregistrer.... Je sais c'est idiot). Quelqu'un pourrait-il m'aiguiller ?

    Merci d'avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    <form action="app/add.php" method="POST" enctype="multipart/form-data">
                    <div class="form-group">
                        <label for="title">Titre</label>
                        <input type="text" class="form-control" id="titre" placeholder="Titre"
                               name="titre" required>
                    </div>
     
                    <div class="form-row">
                        <div class="form-group col-md-7">
                            <label for="adresse">Adresse</label>
                            <input type="text" class="form-control" id="adresse" name="adresse" placeholder="Adresse"
                                   required>
                        </div>
                        <div class="form-group col-md-3">
                            <label for="city">Ville</label>
                            <input type="text" class="form-control" id="ville" name="ville" placeholder="Ville" required>
                        </div>
                        <div class="form-group col-md-2">
                            <label for="cp">Code Postal</label>
                            <input type="text" class="form-control" id="cp" name="cp" placeholder="Code Postal" required>
                        </div>
                    </div>
     
                    <div class="form-row">
                        <div class="form-group col-md-2">
                            <label for="surface">Surface (en m2)</label>
                            <input type="text" class="form-control" id="surface" name="surface"
                                   placeholder="Surface"
                                   required>
                        </div>
                        <div class="form-group col-md-2">
                            <label for="prix">Prix</label>
                            <input type="text" class="form-control" id="prix" name="prix" placeholder="Prix"
                                   required>
                        </div>
                    </div>
     
                    <div class="form-check-inline col-md-2 justify-content-center mb-3">
                        <div class="form-check-inline">
                            <input class="form-check-input" type="radio" id="location" name="type_location_vente"
                                   value="Location"
                                   required>
                            <label class="form-check-label" for="location">Location</label>
                        </div>
                        <div class="form-check-inline">
                            <input class="form-check-input" type="radio" id="vente" name="type_location_vente"
                                   value="Vente"
                                   required>
                            <label class="form-check-label" for="vente">Vente</label>
                        </div>
                    </div>
     
                    <div class="form-group">
                        <label for="description">Description du logement</label>
                        <textarea class="form-control" id="description" rows="3" name="description"></textarea>
                    </div>
                    <div class="form-group custom-file">
                        <input type="file" class="custom-file-input" id="photo" name="photo">
                        <label class="custom-file-label" for="photo">Choisir une image (.jpg, .jpeg, .png ou .svg)</label>
                    </div>
                    <div class="form-group mt-4">
                        <button class="btn btn-primary">Ajouter un logement</button>
                    </div>
                </form>

  2. #2
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    salut,

    pour vérifier si c'est un entier : ctype_digit()
    Le code postal est un entier une fois que l'on a supprimé l'éventuel espace.

    Bon courage

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 6
    Par défaut
    Merci pour cette réponse rapide.

    J'avais déjà essayé avec ctype_digit mais le problème est que le formulaire se soumettait même si la valeur entrée n'était pas un entier. Peut-être l'ai-je mal utilisé ?

    Cordialement.

  4. #4
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    le formulaire se soumet dès que l'utilisateur clique sur "Ajouter un logement".
    De ton côté tu reçois des données via la superglobale $_POST et c'est à ce moment que tu fais tes vérifications
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if ( ! ctype_digit($_POST['surface'] ?? '')) {
        // erreur la surface n'est pas un entier
    }
     
    if ( ! ctype_digit(str_replace(' ', '', $_POST['cp'] ?? ''))) {
        // erreur le code postal n'est pas valide
    }

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 6
    Par défaut
    Super merci beaucoup !

    J'ai finalement réussi à avoir un code fonctionnel et normalement bon (même s'il peut encore être optimisé mais je ne suis que débutant donc ça viendra avec le temps). Je le laisse ci-dessous, ça pourra peut-être servir à d'autres et je met le suejt en résolu.

    Encore merci !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <?php
     
    // VERIFICATION DES CHAMPS OBLIGATOIRES DU FORMULAIRE
     
    // Vérifications pour que les champs "titre", "adresse", "ville" et "type_location_vente" ne soient pas vides
    $titre = $_POST['titre'];
    $adresse = $_POST['adresse'];
    $ville = $_POST['ville'];
    $type = $_POST['type_location_vente'];
     
    if(empty($titre) || empty($adresse) || empty($ville) || empty($type)){
        header('Location: ' . $_SERVER['HTTP_REFERER']);
    }
     
    // Vérification pour que le champs "cp" (code postal) ne soit pas vide,
    // Ne contienne que des entiers et exactement 5 chiffres
    $cp = $_POST['cp'];
    // Si le champ est vide OU si le champ n'est pas un entier comportant exactement 5 chiffres ALORS
    if(empty($cp) || strlen(ctype_digit($cp)) !== 5){
        // Je retourne ici une valeur car ctype_digit() me retourne un booleéen.
        // True si il s'agit seulement d'un entier, false dans le cas contraire (donc exclus les décimaux)
       return header('Location: ' . $_SERVER['HTTP_REFERER']);
    }
     
    // Vérification pour que les champs "surface" et "prix" ne soient pas vides ou ne contiennent que des entiers
    $prix = $_POST['prix'];
    $surface = $_POST['surface'];
    // Si les champs sont vides OU si le champs ne correspond pas à un entier
    if (empty($prix) || !ctype_digit($prix)){
        return header('Location: ' . $_SERVER['HTTP_REFERER']);
    }
    if (empty($surface) || !ctype_digit($surface)){
        return header('Location: ' . $_SERVER['HTTP_REFERER']);
    }

  6. #6
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    allez, parce que t'es étudiant, je vais prendre le temps de t'expliquer :

    quand tu fais $titre = $_POST['titre'];, avec cette notation tu n'as absolument aucune certitude que la clé 'titre' a bien été passée et qu'elle existe au sein du tableau $_POST.
    Dès que tu attends des données de l'extérieur, quelles qu'elles soient, tu dois OBLIGATOIREMENT t'assurer que ces dernière sont bien présentes et qu'elles correspondent EXACTEMENT à ce qui est attendu. Pour une fois, tu dois être hyper paranoïaque . C'est la clé d'un code robuste et sécurisé.
    Donc pour t'assurer que ton code fonctionnera dans tous les cas de figure, tu dois tout tester : l'existence et le type.

    Noter que toutes les valeurs renvoyées par la superglobale $_POST sont des textes.

    Pour la technologie Internet dans sa totalité, tout n'est que texte. La notion de type (entier, décimal, etc...) n'existe pas.
    Le type d'une variable n'existe que dans ton code : PHP, Javascript, etc...

    PHP t'offre plein de manières différentes pour y arriver :
    pour du texte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    if (isset($_POST['titre']) && ($_POST['titre'] !== '') && ($_POST['titre'] != 0)) {
        $titre = $_POST['titre'];
    } else {
        $titre = '';
    }
     
    // ou si tu considères que les valeurs 0 ou '' ou '0' ou null ou array() ou [] 
    // sont quoi qu'il arrive non valides pour le titre tu peux utiliser empty() qui englobe isset()
    if (empty($_POST['titre'])) {
        $titre = '';
    } else {
        $titre = $_POST['titre'];
    }
     
    // utilisation de l'opérateur ternaire
    $titre = isset($_POST['titre']) && ($_POST['titre'] !== '') && ($_POST['titre'] != 0) ? $_POST['titre'] : '';
    $titre = empty($_POST['titre']) ? '' : $_POST['titre'];
     
    // ou en PHP 7
    $titre = empty($_POST['titre'] ?? ''); // équivalent à empty(...)
    pour un entier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // on va partir du principe que la valeur zéro est inacceptable pour la surface
    if (isset($_POST['surface']) && ctype_digit($_POST['surface']) && ($_POST['surface'] > 0)) {
        $surface = (int)$_POST['surface']; // note la présence de (int) qui permet de typer la valeur comme un entier
    } else {
        $surface = 0;
    }
     
    // ou si tu considères que les valeurs 0 ou '' ou '0' ou null ou array() ou [] 
    // sont quoi qu'il arrive non valides pour la surface tu peux utiliser empty() qui englobe isset()
    // comme zéro est inacceptable, on va gagner une étape avec empty() par rapport à isset()
    if (( ! empty($_POST['surface'])) && ctype_digit($_POST['surface'])) {
        $surface = (int)$_POST['surface']; // note la présence de (int) qui permet de typer la valeur comme un entier
    } else {
        $surface = 0;
    }
     
    // utilisation de l'opérateur ternaire
    $surface = (isset($_POST['surface']) && ctype_digit($_POST['surface']) && ($_POST['surface'] > 0)) ? (int)$_POST['surface'] : 0;
    $surface = (( ! empty($_POST['surface'])) && ctype_digit($_POST['surface'])) ? (int)$_POST['surface'] : 0;
     
    // ou en PHP 7
    $surface = ctype_digit($_POST['surface'] ?? '') ? (int)$_POST['surface'] : 0;
    Toutes ces lignes sont totalement équivalentes. C'est la magie de PHP, plein de moyens différents pour arriver au même résultat.
    Avec l'expérience, tu sauras immédiatement quelle est la meilleure approche.

    Enfin, pour le code postal, tu ne traites pas le cas où l'utilisateur insère un espace dedans : "75 001". Ce code postal est valide, sauf que toi tu vas le rejeter parce qu'à cause de l'espace, ctype_digit($cp) va renvoyer false. D'où mon conseil de supprimer tous les espaces avant de passer la valeur à la moulinette ctype_digit() avec str_replace(' ', '', $cp).

    Pour ce qui est de $_SERVER['HTTP_REFERER']), je te déconseille très fortement de t'en servir car cette information n'est pas toujours présente. Encode tes URL à la main (pour l'instant, c'est le plus simple)
    Comme je te l'ai dit : tout ce qui provient de l'extérieur (et $_SERVER['HTTP_REFERER']) en fait partie) n'est pas utilisable dans ton code sans une tonne de précautions.

    Reprends ton code en tenant compte de ma tartine du dessus.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 6
    Par défaut
    Wahou ! Quelle réponse !

    Mille mercis pour ces détails et d'avoir pris le temps de me répondre de la sorte. Cela va grandement m'aider

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 6
    Par défaut
    Bonjour,

    Je reviens vers vous rawsrc. J'ai essayé de prendre un maximum en compte ce que vous m'avez dit.

    Mais j'ai toujours un problème.... Car mon formulaire se soumet si je rentre des lettres dans les champs "surface" et "prix". Or je souhaite que si des lettres sont rentées dans ce champs, la page formulaire se recharge, et non l'envoie de données vers la BDD.

    C'est à dire que lorsque, par exemple, dans mon champs "surface" je rentre "soixante", dans ma BDD, le champs "surface" enregistrera 0 alors que justement je ne souhaite pas enregistrer les données dans ma BDD si les champs "surface" et "prix" = 0.

    Autre problème, si un seul des champs "titre", "adresse", "ville" et "type_logement" est rempli puis le formulaire soumis, je suis redirigé vers list-logements.php, or ces champs n'ont pas besoin d'avoir de traitements particuliers si ce n'est de ne pas être vides (car obligatoires).

    Ai-je mal compris quelque chose ? Je suis vraiment désolé, j'ai débuté php il y a 10 jours...

    Voici le code : (je n'ai pas fait le traitement du code postal encore car je voulais tester déjà avec le prix et la surface)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    if (empty($_POST['titre']) || empty($_POST['adresse']) || empty($_POST['ville']) || empty($_POST['type_logement'])) {
        header('Location: ../index.php');
    } else {
        $titre = $_POST['titre'];
        $adresse = $_POST['adresse'];
        $ville = $_POST['ville'];
        $type = $_POST['type_logement'];
    }
     
    if ((!empty($_POST['prix'])) && ctype_digit($_POST['prix'])) {
        $prix = (int)$_POST['prix'];
    } else {
        header('Location: ../index.php');
    }
     
    if ((!empty($_POST['surface'])) && !ctype_digit($_POST['surface'])) {
        $surface = (int)$_POST['surface'];
    } else {
        header('Location: ../index.php');
    }
     
    require_once 'bdd.php';
     
    // Préparation de la requête
    $sql = $connexion->prepare('INSERT INTO logement (titre, adresse, ville, surface, prix, type_logement) VALUES(:titre, :adresse, :ville, :surface, :prix, :type_logement)'); 
     
    // Protection des données enregistrées
    $sql->bindValue(':titre', $_POST['titre'], PDO::PARAM_STR); //bindValue — Associe une valeur à un paramètre
    // PARAM STR est le type de données attendues // :'title correspond a l'id // ['title'] est la valeur de l'utilisateur
    $sql->bindValue(':adresse', $_POST['adresse'], PDO::PARAM_STR);
    $sql->bindValue(':ville', $_POST['ville'], PDO::PARAM_STR);
    $sql->bindValue(':surface', $_POST['surface'], PDO::PARAM_INT);
    $sql->bindValue(':prix', $_POST['prix'], PDO::PARAM_INT);;
    $sql->bindValue(':type_logement', $_POST['type_logement'], PDO::PARAM_STR);
     
    // On exécute la requête
    $result = $sql->execute(); //$result nous sert a enregistrer en tant que variable le résultat de l'éxecution
     
    //On fait le test
    if ($result) {
        header('Location: ../list-logements.php');
    } else {
        header('Location: ../index.php');
     
    }

  9. #9

  10. #10
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    cela se passe du côté du navigateur.
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <input type="number" name ="name" min="0" step="1">
    c'est une astuce pour n'avoir que des entiers

    Tiens un peu doc pour savoir ce qu'il est possible de faire directement dans un formulaire.

    Attention, cela ne te dispense pas de faire les contrôles dans ton script PHP. Les contrôles des données reçues sont OBLIGATOIRES.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 6
    Par défaut
    Ok, merci à tous les deux .

Discussions similaires

  1. Vérification formulaire PHP
    Par greg73 dans le forum Langage
    Réponses: 31
    Dernier message: 10/03/2009, 12h53
  2. Vérification formulaire PHP
    Par SeThYy dans le forum Langage
    Réponses: 15
    Dernier message: 14/11/2008, 23h49
  3. Réponses: 11
    Dernier message: 10/01/2006, 07h23
  4. [PHP-JS] Formulaire non trouvé dans une fonction
    Par philippe30 dans le forum Langage
    Réponses: 4
    Dernier message: 11/12/2005, 21h53
  5. PHP -- MYSQL -- Formulaire HTML
    Par waybee dans le forum Requêtes
    Réponses: 2
    Dernier message: 28/11/2005, 09h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo