- Fil d'ariane : Accueil du devBlog
- / Détail du billet (Lien direct)
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
[#2] Commentaire rédigé le Vendredi 28 Janvier 2005 à 12:31 par Calak
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
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
[#5] Commentaire rédigé le Vendredi 28 Janvier 2005 à 15:40 par Calak
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?
( à noter que mon code est approximativement 2fois plus rapide que le sien
[#7] Commentaire rédigé le Vendredi 28 Janvier 2005 à 22:20 par Calak
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.


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);
}