11
votes

Comment écrire une bonne insérence de base de données PHP à l'aide d'un tableau associatif

en PHP, je souhaite insérer dans une base de données à l'aide de données contenues dans un tableau associatif de paires de champs / valeur.

Exemple: EM> P>

INSERT INTO table (field1) VALUES (naustyvalue); drop table members; --;


2 commentaires

Je voudrais simplement m'assurer que tout a été validé avant de les ajouter au champ et aux tableaux de valeur.


Voir: Imploder () Convertit NULL en String vide, qui devient alors 0 dans des colonnes entier


7 Réponses :


3
votes

rien de mal avec ça. Je fais la même chose.

Mais assurez-vous de vous mysql_escape () et de citer les valeurs que vous collez dans la requête, sinon vous regardez la vulnérabilité d'injection SQL.

alternativement, vous pouvez utiliser des requêtes paramétrées, dans ce cas, vous pouvez pratiquement passer la matrice en soi, au lieu de construire une chaîne de requête.


1 commentaires

+1 pour des requêtes paramétrées. Lien pour référence: Us.php.net/manual/fr/pdo. États préparés.php



1
votes

La meilleure pratique est d'utiliser une orje (doctrine 2.0), une mise en œuvre de Activerecord (doctrine 1.0, Redbean) ou une implémentation de modèle de table de table (Zend_DB_Table, propul). Ces outils rendront votre vie beaucoup plus facile et géreront beaucoup de lourdes levées pour vous et peuvent vous aider à vous protéger des injections SQL.

Autre que cela, il n'y a rien de mal à ce que vous faites, vous voudrez peut-être abstraire-le dans une classe ou une fonction, de sorte que vous puissiez répéter la fonctionnalité de différents endroits.


0 commentaires

22
votes

La seule chose que je changerais serait d'utiliser Sprintf pour des fins de la lisibilité xxx

et assurez-vous que les valeurs sont échappées.


5 commentaires

Non, non, il suffit d'utiliser PHP.net/Manual/fr/function .mysql-real-escape-string.php sur chaque élément avant insertion


Wow, c'est fantastique. Vous avez ajouté des citations aux valeurs et amélioré la lisibilité. Merci beaucoup!


Je suggérerai d'exécuter Array_Filter () avant, afin de supprimer les valeurs vides de la matrice, elles sont inutiles mais peuvent plus lent votre requête.


@Daniel: Mais ne serait pas Array_Filter () supprimer aussi la chaîne "0"? Cela pourrait ne pas être une bonne idée.


@MARCO: Oui, la chaîne "0" est considérée comme fausse en booléen. Il sera donc supprimé par Array_Filter (sans rappel). Veillez à ce que, selon la situation, cela peut être un problème.



0
votes

Utilisation de l'astuce Sprintf em> mentionné par galen em> dans un réponse précédente , j'ai proposé le code suivant:

$escapedfieldValues = array_map(create_function('$e', 'return mysql_real_escape_string(((get_magic_quotes_gpc()) ? stripslashes($e) : $e));'), array_values($_fields));

$sql = sprintf('INSERT INTO table (%s) VALUES ("%s")', implode(',',array_keys($_fields)), implode('","    ',$escapedfieldValues));

mysql_query($sql);


4 commentaires

Cela ne mérite pas vraiment d'être une réponse. Il devrait être ajouté à la question initiale. Quant à la sécurité, votre meilleur pari ces jours-ci est d'utiliser des requêtes préparées (alias des requêtes paramétrées).


Je suis d'accord, mais si je l'ajoute à la question initiale, les réponses existantes ne feront pas autant de sens? Devrais-je l'ajouter quand même?


Soit a) Ajoutez la majeure partie de celle-ci, à l'exception du code (puisque c'est une réponse potentielle) ou B) l'ajoutez-le dans un titre de section "Mise à jour".


@outis - J'ai choisi l'option A. Merci pour le conseil. Maintenant, ces commentaires n'ont pas beaucoup de sens - les supprimons-nous?



0
votes

J'utilise cela pour récupérer la partie Valeurs de l'insert. Mais cela pourrait être une façon absurde de faire des choses. Les commentaires / suggestions sont les bienvenus.

   function arrayToSqlValues($array)
   {
      $sql = "";
      foreach($array as $val)
      {    
         //adding value
         if($val === NULL)
            $sql .= "NULL";
         else
            /*
            useless piece of code see comments
            if($val === FALSE)
               $sql .= "FALSE";
            else
            */
               $sql .= "'" . addslashes($val) . "'";

         $sql .= ", ";
      };

      return "VALUES(" . rtrim($sql, " ,") . ")";
   }


3 commentaires

Si $ val === true, alors cela vous donne "1".


@Tomhaigh: C'est correct, ce n'est pas un bug. '1' dans la requête SQL est vrai.


Dans ce cas, pourquoi avez-vous fait `$ SQL. =" faux ";` pour faux? Ne serait-il pas préférable d'être cohérent?



0
votes

Il y a un problème avec NULL (dans la réponse acceptée) des valeurs converties en chaîne vide "". Donc, c'est correction, NULL devient NULL sans citations: xxx

utilisation: xxx


0 commentaires

0
votes

Si vous souhaitez améliorer votre approche et ajouter la possibilité de validation d'entrée et d'assainissement, vous voudrez peut-être le faire:

function insertarray($table, $arr){
   foreach($arr as $k => $v){
      $col[] = sanitize($k);
      $val[] = "'".sanitize($v)."'";
   }

   query('INSERT INTO '.sanitize($table).' ('.implode(', ', $col).') VALUES ('.implode(', ', $val).')' );
}


0 commentaires