8768 sujets

Développement web côté serveur, CMS

Bonjour,

Je cherche à transférer un excel sur une bdd. Sur mon Excel, ma colonne "Nom" contient sur certaines lignes une apostrophe, du coup à partir de la ligne avec l'apostrophe plus aucune n’apparaît sur ma bdd.
Savez-vous comment gérer les apostrophes?
Merci d'avance

Voici mon code:
<?php

if(isset($_POST["numero_client"]))
{
$connect = new PDO("mysql:host=localhost;dbname=resultat_secto", "root", "root");
$temps = $_POST["temps"];
$nom = $_POST["nom"];

for($count = 0; $count < count($nom); $count++)
{

$query .= "
INSERT INTO tbl_sectorisation(temps, nom)
VALUES ( '".$temps[$count]."', '".$nom[$count]."');
";
}

$statement = $connect->prepare($query);
$statement->execute();
}
?>
Bonjour !

Il y a plusieurs problèmes dans le code d'origine

- Il construit manuellement la requête avec des variables externes (ce qui représente un énorme risque de sécurité)
- Malgré qu'il utilise les bons outils (PDO), il n'est pas bien utilisé ce qui réduit les performances

Petite explication technique :

Tout d'abord, il ne faut pas chercher à construire manuellement votre requête.
Indiquez simplement un paramètre (ex. :nom), et ensuite associez lui une valeur (via la méthode bindValue). Votre SGBD s'occupera du reste.
Vous ne devez plus échapper les caractères spéciaux de vos variables, il va s'en occuper pour vous.

Quand vous effectuez une requête préparée (via la méthode prepare), vous envoyez en réalité la requête à votre SGBD qui va l'analyser une seule fois.
Ensuite, à chaque passage dans la boucle for, vous allez simplement associer la valeur de chaque paramètre (via la méthode bindValue), et lui envoyer ces deux valeurs (via la méthode execute).
Votre SGBD n'a plus besoin de préparer la requête, il va juste utiliser vos valeurs et effectuer votre requête. Si vous avez 1000 lignes à insérer, il va donc préparer une seule fois votre requête et exécuter celle-ci 1000 fois avec des valeurs différentes. Ce qui est nettement plus performant que de devoir exécuter 1000 fois une requête construire "à la main".

Bref, pouvez-vous tester cette modification de votre code ?

J'ai pris pour hypothèse que vos deux champs (temps et nom) sont des colonnes de type texte (CHAR, VARCHAR ou TEXT).


if (isset($_POST["numero_client"])) {
    $connect = new PDO("mysql:host=localhost;dbname=resultat_secto", "root", "root");
    $temps = $_POST["temps"];
    $nom = $_POST["nom"];

    // Requête
    $query = 'INSERT INTO tbl_sectorisation(temps, nom)';
    $query .= 'VALUES (:temps, :nom)';

    // On prépare la requête
    $statement = $connect->prepare($query);

    // Pour chaque ligne :
    // - On passe les valeurs (plus besoin de préparer la requête)
    // - On exécute    
    for ($count = 0; $count < count($nom); $count++) {

        // On paramètre la requête
        $statement->bindValue('temps', $temps[$count], PDO::PARAM_STR);
        $statement->bindValue('nom', $nom[$count], PDO::PARAM_STR);

        // On l'exécute
        $statement->execute();
    }
}


Enfin, par sécurité, veillez à utiliser un autre utilisateur que le compte root pour vous connecter à votre base de données. Çà vous évitera de sales blagues. Smiley cligne

Très cordialement,
Modifié par Bouchon (27 Jul 2020 - 17:31)
Meilleure solution
Bonjour,
Je vous remercie pour votre explication, c'est super claire! Pour les identifiants, c'est peut-être une question bête mais je peux mettre ce que je veux ?
Dernière question, peut-on gérer d'écraser la bdd si elle est déjà existante sur mysql?
Modifié par Elnofey (28 Jul 2020 - 09:14)