Aller au contenu
Télécharger Firefox 2

Manipulation de tableaux associatifs

En PHP, la fonction print_r() affiche les indexes et les éléments d'un tableau. Il en existe une autre très intéressante qui permet de retourner tout les indexes d'un tableau: array_keys() . On peut ainsi facilement accéder à la manière d'un phpinfo() aux informations concernant la configuration du système en accédant aux variables superglobale.

Un exemple simple d'utilisation

Nous désirons traiter les informations soumises via un formulaire avant de les insérer dans une base de données.

     // On mémorise la configuration concerant les magic_quotes_gpc
     define("__CFG__MQGPC__", get_magic_quotes_gpc());
     // On crée un tableau avec les différents noms de champs de formulaires postés
     $tableau2cles = array_keys($_POST);
     // On parcourt le tableau
     foreach($tableau2cles as $cle) {
          // Si les magic_quotes sont activés on renvoit la chaine sans traitement
          $_POST[$cle] = (__CFG__MQGPC__) ? $_POST[$cle] : addslashes($_POST[$cle]);
     }

Utilisation dans le cadre d'une fonction

Il est parfois long d'écrire une requête SQL surtout lorsque l'on doit traiter plusieurs colonnes. Voici un exemple de fonction d'insertion dans le cadre d'une requête MySQL.

     function insertTuple($table, $valueTab) {
          $_RQ = "INSERT INTO `" . $table . "` ";
          // Génération des champs
          $_virgule = "";
          $_RQ .= " (";
          $keys = array_keys($valueTab);
          foreach ($keys as $key) {
               $_RQ .= $_virgule . " `" . $key . "`";
               $_virgule = ", ";
          }
          $_RQ .= " ) VALUES (";
          // Génération des valeurs
          $_virgule = "";
          $keys = array_keys($valueTab);
          foreach ($keys as $key) {
               $val = (is_string($valueTab["$key"])) ? "'" . $valueTab["$key"] . "'" : $valueTab["$key"];
               $_RQ .= $_virgule . $val;
               $_virgule = ", ";
          }
          $_RQ .= ")";
          if (mysql_query($_RQ)) {
               return mysql_insert_id();
          }
          else {
               echo "[insertTuple] Error (" . mysql_error() . ") : " . $_RQ;
          }
     }

     // Usage
     // Insertion dans une table utilisateur "tbl_utilisateur" d'informations soumises par formulaire
     $infoTab = array("nom"=>$_POST["nom"], "prenom"=>$_POST["prenom"]);
     // Appel à la fonction qui renvoit la clé généré lors de l'insertion
     $utilisateurId = insertTuple("tbl_utilisateur", $infoTab);

Cette technique consiste donc :

  • à créer un tableau avec pour chaque index, représentant le nom de la colonne à remplir, une valeur correspondante.
  • à passer le tableau en paramètre de la fonction insertTuple qui se charge de construire la requête et de l'exécuter. Si l'insertion se fait, la fonction retourne l'identifiant de l'enregistrement inséré.

... sur le même principe je vous laisse imaginer une version de mise à jour de données : updateTuple() ^^


Commentaires


[#1] Commentaire rédigé le Vendredi 28 Janvier 2005 à 12:29 par Calak

Pourquoi utiliser de grosses boucles bien gourmandes? ;-)

Voici le code que j'utilise.
J'ai fais des tests par rapport à ton code, en retirant la partie "mysql" ( afin de mettre en avant la vitesse de l'algo de parsing )
Voici deux version de mon code, une version lisible et une autre bcp moins. Mais j'ai remarqué lors de mes tests que la version "all in-line" est sensiblement plus rapide ;-)

function insert_array($table, $array)
{
$sql = 'INSERT INTO `' . $this->add_prefix($table) . '` (`' . implode('`, `', array_keys($array)) . '`) VALUES (' . implode(', ',array_map($this->protect_quote($value), $array)) . ')';
return $this->query($sql);
}
function insert_array2($table, $array)
{
$sql = 'INSERT INTO `' . $this->add_prefix($table) . '` ';
$sql .= '(`' . implode('`, `', array_keys($array)) . '`) ';
$sql .= 'VALUES (' . implode(', ',array_map($this->protect_quote($value), $array)) . ')';
return $this->query($sql);
}

[#2] Commentaire rédigé le Vendredi 28 Janvier 2005 à 12:31 par Calak

oops j'oubliais une fonction, celle qui rajoute les ' ' dans le cas où la valeur est une string.
C'est la partie qui bouffe le plus de temps dans tout l'algo.
Au début j'étais passé par "create_function" mais ca prend bcp trop de ressources. Je suis donc passé par une fonction extérieure.

function protect_quote(&$value)
{
if (is_string($value)) $value = "'" . $value . "'";
}

[#3] Commentaire rédigé le Vendredi 28 Janvier 2005 à 12:40 par Calak

désolé, 3 commentaires à la suite :|

concernant ton premier post, il pourrait être par mal optimisé aussi. Je ne fais pas de tests de bench car là, ça sert même à rien:

// On mémorise la configuration concerant les magic_quotes_gpc
define("__CFG__MQGPC__", get_magic_quotes_gpc());
// On crée un tableau avec les différents noms de champs de formulaires postés
$tableau2cles = array_keys($_POST);
// Si les magic_quotes sont activées
if ((__CFG__MQGPC__))
{
// On parcourt le tableau
foreach($tableau2cles as $cle) {
$_POST[$cle] = addslashes($_POST[$cle]);
}
}

j'ai corrigé ça en live, donc j'ai p-e loupé un point-virgule ou une bétise comme ça :p

[#4] Commentaire rédigé le Vendredi 28 Janvier 2005 à 12:47 par solo

Bien vu pour le implode. :)

Par contre tu pourrais remplacer ta fonction par une écriture conditionnelle de la forme:

"(expression) ? val1 : val2;" ^^

[#5] Commentaire rédigé le Vendredi 28 Janvier 2005 à 15:40 par Calak

J'ai essayé mais n'y suis pas arrivé. En fait, array_map attend une fonction.
La fonction en elle même j'ai essayé de l'otimiser.

Sinon, si je ne voulais pas passer par array_map, je devais faire une boucle, et ça aurait bouffé du temps aussi.

Quel serait ta proposition? :D
( à noter que mon code est approximativement 2fois plus rapide que le sien :p )

[#6] Commentaire rédigé le Vendredi 28 Janvier 2005 à 15:45 par solo

Que penserais-tu de toujours mettre des "'" pour englober tes valeurs. C'est tout à fait jouable si on prend en compte que les champs int de MySQL sont alimentables même si les valeurs insérées sont entourées de simples quotes.

Je ne pense pas que ça soit aussi bourrin que ça en a l'air étant donné que MySQL et PHP(4) ne sont pas pas si sévères quand au typage des données traitées.

[#7] Commentaire rédigé le Vendredi 28 Janvier 2005 à 22:20 par Calak

awi!
Et du coup, on gagne encore près de 10% de temps d'exécution ^_^;
C'est vrai, je n'y aurais pas pensé à mettre des quote pour les int aussi...
Ou bien c'était trop simple pour y penser, ou bien le c/c++ et autres languages "évolués" font que perd certaines habitudes ^^

L'ajout de commentaire a été désactivé pour ce billet.

Trackbacks

Pisteurs vers ce billet (trackbacks entrant)

Il n'y a pas encore de pisteurs pour ce billet.

Pistés par ce billet (trackbacks sortant)

Il n'y a pas encore de pisteurs effectué par ce billet.


A propos du billet

  • Auteur : Thanh
  • Thématique :
    Développement, PHP
  • Publié : Mercredi 03 Novembre 2004 à 03h58
  • Nombre de lectures : 3574
  • Nombre de commentaires : 7
  • Ping : Les trackbacks sont fermés.
  • Tags :
Avatar de Thanh

Raccourcis

Rechercher un billet

Sous Rubriques

Photo Pif

Photopif