Précédent   Forum du club des développeurs et IT Pro > PHP > Langage > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, etc. pour PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 24/07/2011, 11h48   #1
rawsrc
Modérateur
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 2 581
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 36
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 2 581
Points : 6 018
Points : 6 018
Envoyer un message via Skype™ à rawsrc
Par défaut Tableau PHP sans transtypage des clefs et clefs décimales

Bonjour,

Faisant suite à mon post sur le forum PHP/Syntaxe, vous trouverez ci-dessous le code d'une classe qui gère un tableau PHP brut sans aucun transtypage des clefs. Il est même possible d'y définir des clefs décimales.

IMPORTANT : Le parcours de ce tableau ne peut être fait en utilisant foreach() ou each(). Veuillez vous reporter à l'en-tête de la classe.
Code :
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?php 
 
/**
 * Copyright (C) 2011+ Martin Lacroix
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * @license GNU General Public License Version 3 (GPLv3)
 * @link http://www.gnu.org/licenses/
 */
 
/**
 * PHP_VER   : PHP 5.3+ 
 * LIBRARIES : 
 * KEYWORDS  : BASIC RAW ARRAY KEY VALUE DISABLE WITHOUT AUTO CASTING INTEGER FLOAT
 *             TABLEAU BRUT CLE CLEF VALEUR SANS TRANSTYPAGE ENTIER DECIMAL
 * 
 * Class with array access methods that manage a special array without auto-casting of the keys
 * A key equals to '1' (string) will be different from another that is equal to 1 (integer)
 * It is even possible to have now a float number as one key of the array.
 * Ex:
 *    $a = new SimpleArray();
 *    $a['123.456'] = 'string';  # the key is a string
 *    $a[123.456]   = 'float';   # the key is a float
 *    $a[]          = 'value';   # standard definition
 * 
 * IMPORTANT: 
 *    Because of some PHP limitations (or features...), it is impossible to walk through the array 
 *    using foreach() or each().
 *    The right way to walk through is:
 *       $a->rewind();
 *       while($a->valid()) {
 *          # do some stuff using $a->key() and $a->current()
 *          $a->next();
 *       }
 * 
 * 
 * Classe gérant un tableau spécial qui ne transtype pas ses clefs. Une clé '1' sera différente de 1
 * Il est même possible de définir maintenant des nombres décimaux en guise de clef.
 * Ex :
 *    $a = new SimpleArray();
 *    $a['123.456'] = 'string';  # la clef est une chaine
 *    $a[123.456]   = 'float';   # la clef est un décimal
 *    $a[]          = 'value';   # définition standard
 * 
 * IMPORTANT: 
 *    A cause de certaines limitations de PHP (ou fonctionnalités...), il est impossible de parcourir le tableau
 *    en utilisant foreach() ou each().
 *    Voici la bonne manière pour le parcourir :
 *       $a->rewind();
 *       while($a->valid()) {
 *          # opérations utilisant $a->key() et $a->current()
 *          $a->next();
 *       }
 * 
 * @package tools
 * @version 1.0.0
 * @author Martin Lacroix
 */
class SimpleArray implements ArrayAccess, Iterator, Countable {
 
   private $_data  = array();
   private $_keys  = array();
   private $_index = -1;
 
   /**
    * ARRAYACCESS INTERFACE
    */
   function offsetExists($offset) {
      return (FALSE !== array_search($offset, $this->_keys, TRUE));
   }
 
   function offsetGet($offset) {
      $index = array_search($offset, $this->_keys, TRUE);
      if (FALSE !== $key) {
         return $this->_data[$index];
      }
   }
 
   function offsetSet($offset, $value) {
      if (NULL === $offset) {
         $index = ++$this->_index;
         $offset = $index;
      }
      else {
         $index = array_search($offset, $this->_keys, TRUE);
         if (FALSE === $index) {
            $index = ++$this->_index;
         }
      }
      $this->_data[$index] = $value;
      $this->_keys[$index] = $offset;
   }
 
   function offsetUnset($offset) {
      $index = array_search($offset, $this->_keys, TRUE);
      if (FALSE !== $key) {
         unset($this->_data[$index]);
         unset($this->_keys[$index]);
      }
   }
 
   /**
    * ITERATOR INTERFACE
    */
   function current() {
      return $this->_data[key($this->_keys)];
   }
 
   function key() {
      return current($this->_keys);
   }
 
   function next() {
      next($this->_keys);
      return $this->current();
   }
 
   function rewind() {
      reset($this->_keys);
   }
 
   function valid() {
      return (FALSE !== $this->key());
   }
 
   /**
    * COUNTABLE INTERFACE
    */
   function count() {
      return count($this->_keys);
   }
 
   ###########################################
 
   /**
    * Vérifie si une valeur est dans la tableau
    * @param mixed $pNeedle
    * @param bool $pStrict
    * @return bool
    */
   function inArray($pNeedle, $pStrict = TRUE) {
      return (FALSE !== array_search($pNeedle, $this->_data, $pStrict));
   }
 
   /**
    * Vérifie si une clé existe
    * @param mixed $pKey (Strict comparison)
    * @return bool
    */
   function keyExists($pKey) {
      return (FALSE !== array_search($pKey, $this->_keys, TRUE));
   }
 
   /**
    * Cherche une valeur et renvoie la clé correspondante,
    * sinon renvoie FALSE
    * @param mixed $pNeedle
    * @param bool $pStrict
    * @return mixed|FALSE
    */
   function search($pNeedle, $pStrict = TRUE) {
      $index = array_search($pNeedle, $this->_data, $pStrict);
      if (FALSE !== $index) {
         return $this->_keys[$index];
      }
   }
}
 
?>
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/08/2011, 00h35   #2
doctorrock
Rédacteur
 
Avatar de doctorrock
 
Homme Julien Pauli
Architecte de système d'information
Inscription : mai 2006
Messages : 603
Détails du profil
Informations personnelles :
Nom : Homme Julien Pauli
Âge : 30
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Architecte de système d'information
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : mai 2006
Messages : 603
Points : 3 926
Points : 3 926
Sympa

En effet, foreach() et each() vont utiliser l'itérateur d'une manière spéciale, codée ici http://lxr.php.net/opengrok/xref/PHP...terfaces.c#198.

Tu peux clairement lire que si la clé est de type double, il la convertit en long (entier) , ligne 228.

Appeler soi-même key() ne lance pas la fonction zend_user_it_get_current_key() responsable de ce cast.
__________________
.: Expert contributeur certifié PHP/ZF :.
Mes articles - Twitter - GitHub
doctorrock est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 01/09/2011, 08h12   #3
rawsrc
Modérateur
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 2 581
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 36
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 2 581
Points : 6 018
Points : 6 018
Envoyer un message via Skype™ à rawsrc
Citation:
Envoyé par doctorrock Voir le message
Sympa

En effet, foreach() et each() vont utiliser l'itérateur d'une manière spéciale, codée ici http://lxr.php.net/opengrok/xref/PHP...terfaces.c#198.

Tu peux clairement lire que si la clé est de type double, il la convertit en long (entier) , ligne 228.

Appeler soi-même key() ne lance pas la fonction zend_user_it_get_current_key() responsable de ce cast.
Franchement, merci.
Je ne m'étais jamais mais alors jamais intéressé à l'envers du décor du PHP et je dois dire que c'est fort instructif (et comme toujours tout s'explique)
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2011, 13h48   #4
doctorrock
Rédacteur
 
Avatar de doctorrock
 
Homme Julien Pauli
Architecte de système d'information
Inscription : mai 2006
Messages : 603
Détails du profil
Informations personnelles :
Nom : Homme Julien Pauli
Âge : 30
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Architecte de système d'information
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : mai 2006
Messages : 603
Points : 3 926
Points : 3 926
La première force de l'open source réside dans son nom
__________________
.: Expert contributeur certifié PHP/ZF :.
Mes articles - Twitter - GitHub
doctorrock est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 12h55.


 
 
 
 
Partenaires

Hébergement Web