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 :

CRUD est t il correct Merci


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Philcmoi
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 666
    Par défaut CRUD est t il correct Merci
    Bonjour je bloc sur des choses tres simple.
    Ces requettes sql sont t elles correctes?
    La table Orders
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TABLE IF NOT EXISTS `orders` (
      `order_number` int(11) NOT NULL AUTO_INCREMENT,
      `conducteur` varchar(100) DEFAULT NULL,
      `lieudepart` varchar(500) DEFAULT NULL,
      `lieuarrive` varchar(255) DEFAULT NULL,
      `participation` double DEFAULT NULL,
      `datedepart` datetime DEFAULT NULL,
      `datearrive` datetime DEFAULT NULL,
      `idmembre` int(11) DEFAULT NULL,
      PRIMARY KEY (`order_number`),
      KEY `fk_orders_membre_idx` (`idmembre`)
    ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
    db_config
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	$con = mysqli_connect($dbhost, $dbuser, $dbpass , $db) or die($con);
    // 	mysqli_set_charset($con, "utf8");
    	if(mysqli_connect_errno())
    	{
    	    echo "Connection Fail".mysqli_connect_error();
    	}
    	else {echo "connexion reusite";}
    CREATE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $sql = "INSERT INTO `orders` (`order_number`, `conducteur`, `lieudepart`, `lieuarrive`, `participation`, `datedepart`, `datearrive`, `idmembre`) VALUES ('$conducteur','$lieudepart','$lieuarrive','$participation','$datedepart','$datearrive',NULL)";
    READ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $query = "SELECT * FROM orders WHERE datedepart BETWEEN '".$_POST["datedepart"]."' AND '".$_POST["datearrive"]."'ORDER BY order_number desc ";
        $result = mysqli_query($con, $query);
    UPDATE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        $sql = "UPDATE 'orders' SET 'conducteur' = '$conducteur' , 'lieudepart' = '$lieudepart', 'lieuarrive' = '$lieuarrive', 'participation' = '$participation', 'datedepart' = '$datedepart', 'datearrive' = '$datearrive' WHERE 'orders'.'order_number' = '$orders_number'";
     
        $query=mysqli_query($con,$sql);
    DELETE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        $req = "DELETE FROM `orders` WHERE `orders`.`order_number` = '$order_number'";

  2. #2
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE IF NOT EXISTS `orders` (
    Le délimiteur ` n'est utile pour que les noms de colonnes/tables ayant un caractère spécial (espace, caractère accentué)
    Mieux vaut utiliser MySQL en mode strict et le délimiteur standard "
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    `order_number` int(11) NOT NULL AUTO_INCREMENT,
    Préciser la longueur "(11)" est obsolète. Tu devrais ne pas la préciser.
    S'agissant d'une PRIMARY KEY, le NOT NULL est implicite.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    KEY `fk_orders_membre_idx` (`idmembre`)
    S'il s'agit d'une clef étrangère, tu pourrais remplacer cela par une contrainte, ex. :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CONSTRAINT FOREIGN KEY (idmembre) REFERENCES membres (id) ON UPDATE CASCADE ON DELETE RESTRICT

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $con = mysqli_connect($dbhost, $dbuser, $dbpass , $db) or die($con);
    Il existe PDO, qui est considéré comme le standard PHP de connexion aux bdd.
    => https://www.php.net/pdo


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    else {echo "connexion reusite";}
    C'est mal présenté


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sql = "INSERT INTO `orders` (`order_number`, `conducteur`, `lieudepart`, `lieuarrive`, `participation`, `datedepart`, `datearrive`, `idmembre`) VALUES ('$conducteur','$lieudepart','$lieuarrive','$participation','$datedepart','$datearrive',NULL)";
    Illisible et variables non échappées (de ce qu'on en voit).

    MySQL propose une syntaxe INSERT très utile, couplée au HEREDOC PHP http://www.php.net/heredoc ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $sql = <<<SQL
        INSERT INTO orders
        SET
            order_number = '{$conducteur}',
            conducteur = '{$lieudepart}',
            lieudepart = '{$lieuarrive}',
            ...
        SQL;
    Comme tu peux le remarquer, on voit tout de suite les décalages de colonnes
    Avec PDO on échappe les valeurs avec PDO::quote() ou en préparant les requêtes.


    Même chose pour les autres requêtes.

  3. #3
    Membre éclairé Avatar de Philcmoi
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 666
    Par défaut
    Merci.
    Je prefere ne pas utiliser pdo et utuliser msqli.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    Bonjour,

    Ce qui vous échappe c'est que ce code est vulnérable aux injections SQL! c'est la voie royale pour se faire hacker. Top 10 Owasp.
    C'est aussi pour ça qu'on utilise des APIs comme PDO, des frameworks, c'est pour faciliter les manipulations et aussi ne pas devoir bricoler avec des escape strings tout en se demandant quel est le charset en vigueur (qui a de l'importance).
    Désolée de le dire mais c'est du code selon les standards d'il y a 20 ans, et déjà vulnérable à l'époque Je pense que vous vous êtes inspirés de mauvais tutos, peut-être bien référencés mais anciens et qui concentrent les mauvaises pratiques.
    Au minimum utilisez des requêtes paramétrées.

    Jamais, au grand jamais je n'engagerai un développeur qui me propose ce code, ou alors je l'envoie en rééducation si je sens qu'il y a encore du potentiel

    Le data model en soi n'est pas choquant, il y a juste les varchar un peu surdimensionnés probablement mais sans avoir the full picture je ne vais pas m'engager dans une critique détaillée.

    Je remarque quand même que vous mélangez l'anglais et le français (orders, membres). En général dans les projets d'une certaine envergure on normalise les noms d'objets en anglais, et aussi les variables en code. Pour un projet perso on s'en fiche mais si vous comptez partager le repo sur github l'anglais est fortement souhaitable car il est plus facile pour les autres développeurs du monde entier d'appréhender le code pour y faire des contributions.

    Et pour continuer sur votre lancée, vous pouvez harmoniser la convention de nommage: ajouter des underscores aux champs tels que lieudepart, lieuarrive, etc. Ca donne une certaine prévisibilité au code et par la même occasion ça diminue le risque d'alias involontaire.

  5. #5
    Membre éclairé Avatar de Philcmoi
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 666
    Par défaut
    Merci mais je n'ai pas précisé que je fais avant du htmlchar ou htmlentities

  6. #6
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 322
    Billets dans le blog
    17
    Par défaut
    Citation Envoyé par Philcmoi Voir le message
    Merci mais je n'ai pas précisé que je fais avant du htmlchar ou htmlentities
    htmlspecialchars() et htmlentities() servent à échapper du HTML à l'affichage, pas à échapper une valeur SQL à insérer
    Le format du contenu de ta base de données devrait être indépendant du support final, autrement que se passe-t-il si tu fais un export en vu d'un extract CSV ou autre ?
    On échappe les valeurs SQL avec une requête préparée ou avec PDO::quote() / mysqli::real_escape_string()

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 599
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par binarygirl Voir le message
    Le data model en soi n'est pas choquant, il y a juste les varchar un peu surdimensionnés probablement mais sans avoir the full picture je ne vais pas m'engager dans une critique détaillée.
    C'est tout le contraire

    • absence des déclaratives foreign key, ce qui compromet l'intégrité des données
    • présence des colonnes `conducteur`, `lieudepart` et `lieuarrive` qui ne dépendent pas fonctionnellement de l'identifiant et constituent donc un viol de la deuxième forme normale
    • pléthore de colonnes "nullables", symptomatiques d'une modélisation à l'emporte pièces
    • mélange de noms de colonne en anglais et en français, source de confusion. Soit on travaille sur un projet international et l'anglais s'impose, soit ce n'est pas le cas et la langue locale s'impose
    • typage et longueur des données inadaptés


    Tout est à revoir, en commençant par le début : les règles de gestion, le dictionnaire de données et le MCD, les tables ne sont qu'une conséquence de ces étapes préalables.

  8. #8
    Membre éclairé Avatar de Philcmoi
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 666
    Par défaut
    Voici ma base de donnees.
    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
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
     
    -- MySQL Workbench Forward Engineering
     
    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
     
    -- -----------------------------------------------------
    -- Schema mydb
    -- -----------------------------------------------------
    -- -----------------------------------------------------
    -- Schema philippe
    -- -----------------------------------------------------
     
    -- -----------------------------------------------------
    -- Schema philippe
    -- -----------------------------------------------------
    CREATE SCHEMA IF NOT EXISTS `philippe` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ;
    USE `philippe` ;
     
    -- -----------------------------------------------------
    -- Table `philippe`.`membre`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `philippe`.`membre` (
      `idmembre` INT NOT NULL AUTO_INCREMENT,
      `email` VARCHAR(100) NOT NULL,
      `pseudo` VARCHAR(100) NOT NULL,
      `token` VARCHAR(10000) NOT NULL,
      `password` VARCHAR(10000) NOT NULL,
      `role` VARCHAR(25) NOT NULL DEFAULT 'visiteur',
      PRIMARY KEY (`idmembre`))
    ENGINE = InnoDB
    AUTO_INCREMENT = 18
    DEFAULT CHARACTER SET = utf8mb3;
     
     
    -- -----------------------------------------------------
    -- Table `philippe`.`orders`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `philippe`.`orders` (
      `order_number` INT NOT NULL AUTO_INCREMENT,
      `conducteur` VARCHAR(100) NULL DEFAULT NULL,
      `lieudepart` VARCHAR(500) NULL DEFAULT NULL,
      `lieuarrive` VARCHAR(255) NULL DEFAULT NULL,
      `participation` DOUBLE NULL DEFAULT NULL,
      `datedepart` DATETIME NULL DEFAULT NULL,
      `datearrive` DATETIME NULL DEFAULT NULL,
      `idmembre` INT NULL DEFAULT NULL,
      PRIMARY KEY (`order_number`),
      INDEX `fk_orders_membre_idx` (`idmembre` ASC) VISIBLE)
    ENGINE = InnoDB
    AUTO_INCREMENT = 25
    DEFAULT CHARACTER SET = utf8mb3;
     
     
    -- -----------------------------------------------------
    -- Table `philippe`.`trajet`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `philippe`.`trajet` (
      `idtrajet` INT NOT NULL AUTO_INCREMENT,
      `depart` VARCHAR(255) NULL DEFAULT NULL,
      `arrive` VARCHAR(255) NULL DEFAULT NULL,
      `latDepart` FLOAT NULL DEFAULT NULL,
      `longDepart` FLOAT NULL DEFAULT NULL,
      `latArrive` FLOAT NULL DEFAULT NULL,
      `longArrive` FLOAT NULL DEFAULT NULL,
      `idmembre` INT NULL DEFAULT NULL,
      `order_number` INT NULL DEFAULT NULL,
      PRIMARY KEY (`idtrajet`),
      UNIQUE INDEX `idtrajet` (`idtrajet` ASC) VISIBLE,
      UNIQUE INDEX `idtrajet_2` (`idtrajet` ASC) VISIBLE,
      UNIQUE INDEX `idtrajet_3` (`idtrajet` ASC) VISIBLE,
      UNIQUE INDEX `idtrajet_4` (`idtrajet` ASC) VISIBLE,
      UNIQUE INDEX `idtrajet_5` (`idtrajet` ASC) VISIBLE,
      INDEX `fk_trajet_membre1_idx` (`idmembre` ASC) VISIBLE,
      INDEX `fk_trajet_orders1_idx` (`order_number` ASC) VISIBLE)
    ENGINE = InnoDB
    AUTO_INCREMENT = 15
    DEFAULT CHARACTER SET = utf8mb4
    COLLATE = utf8mb4_0900_ai_ci;
     
     
    SET SQL_MODE=@OLD_SQL_MODE;
    SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
    SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

  9. #9
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 599
    Billets dans le blog
    10
    Par défaut
    Bonjour,


    Citation Envoyé par Philcmoi Voir le message
    La table Orders
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    CREATE TABLE IF NOT EXISTS `orders` (
      `order_number` int(11) NOT NULL AUTO_INCREMENT,
      `conducteur` varchar(100) DEFAULT NULL,
      `lieudepart` varchar(500) DEFAULT NULL,
      `lieuarrive` varchar(255) DEFAULT NULL,
      `participation` double DEFAULT NULL,
      `datedepart` datetime DEFAULT NULL,
      `datearrive` datetime DEFAULT NULL,
      `idmembre` int(11) DEFAULT NULL,
      PRIMARY KEY (`order_number`),
      KEY `fk_orders_membre_idx` (`idmembre`)
    ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
    Cette table est très mal modélisée
    Conducteur, lieu de départ et lieu d'arrivée n'ont rien à faire ici ! À remplacer par des clefs étrangères


    Citation Envoyé par Philcmoi Voir le message
    READ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $query = "SELECT * FROM orders WHERE datedepart BETWEEN '".$_POST["datedepart"]."' AND '".$_POST["datearrive"]."'ORDER BY order_number desc ";
        $result = mysqli_query($con, $query);
    Il ne faut JAMAIS coder SELECT * dans un traitement
    • transport de données inutiles qui chargent le réseau
    • utilisation des éventuels index couvrants compromise
    • analyses d'impact difficiles
    • et surtout, la requête est instable, si la table ou la vue évolue, le résultat de la requête est impacté !


    Il n'y a que dans un test d'existence (NOT) EXISTS, qu'on peut utiliser SELECT *, car un test d'existence ne transporte aucune donnée, juste un booléen
    Mais même dans ce cas je préfère ne pas l'utiliser, car ça incite les débutants à l'utiliser dans d'autres contextes.
    C'est pourquoi je lui préfère SELECT 1 par exemple


    Citation Envoyé par Séb. Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    KEY `fk_orders_membre_idx` (`idmembre`)
    S'il s'agit d'une clef étrangère, tu pourrais remplacer cela par une contrainte, ex. :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CONSTRAINT FOREIGN KEY (idmembre) REFERENCES membres (id) ON UPDATE CASCADE ON DELETE RESTRICT
    Si c'est une FK, il faut déclarer la contrainte, sans quoi, l'intégrité des données n'est pas garantie.
    Une base de données qui n'est pas intègre ne vaut pas grand chose une facture sans ses lignes de facture est même illégale !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 06/11/2008, 11h55
  2. L'objet est-il initialisé correctement?
    Par Paul Van Walleghem dans le forum VB.NET
    Réponses: 0
    Dernier message: 18/07/2008, 17h28
  3. Réponses: 2
    Dernier message: 01/04/2008, 22h35
  4. [XML] Lequel est le plus correct ?
    Par Sensei.f dans le forum XML/XSL et SOAP
    Réponses: 17
    Dernier message: 24/10/2006, 15h27
  5. Réponses: 5
    Dernier message: 11/02/2006, 08h12

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