Précédent   Forum des professionnels en informatique > PHP > Langage > Syntaxe
Syntaxe Forum d'entraide sur la syntaxe de PHP et la POO. Avant de poster -> FAQ syntaxe, Cours d'initiation et cours de POO
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/11/2010, 07h28   #1
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 691
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 691
Points : 3 258
Points : 3 258
Par défaut ArrayObject à plusieurs dimensions : Accéder via une méthode

Salut à tous

Je cherche le moyen d'accéder par le biais d'une méthode à un élément d'un Objet ArrayObject à 2 dimensions (par exemple).

A une dimension, pas de problème :
Code :
1
2
3
4
5
 
$arrayObj = new ArrayObject(array('premier' => 'un'));
echo $arrayObj['param'];
// Ou
echo $arrayObj->offsetGet('premier');
A 2 dimensions aussi :
Code :
1
2
3
4
5
 
$arrayObj = new ArrayObject(array('premier' => array('un' => '1')));
$arrayObj['premier']['un'].'<br />';
// Ou
echo $arrayObj->premier['un'].'<br />';
Mais par le biais d'une méthode, alors là ???
Quelque chose du genre :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
class UneClasse {
    private $arrayObj;
 
    public function __construct() {
        $this->arrayObj = new ArrayObject(array('premier' => array('un' => '1')));
    }
 
    public function getArrayObj($key) {
        return ???
    }
}
Je pensais que faire quelque chose du genre pouvait se faire :
Code :
1
2
3
4
5
 
    public function getArrayObj($key) {
        // ---> $key serait une chaine comme : premier['un']
        return $this->arrayObj->{$key};
    }
Mais ça marche pô
Puis passer une chaine en argument pour un clé à 2 dimension me semble pas très zen.

Parcourir (genre foreach) le tableau me parait ingérable (beaucoup trop hasardeux).

Sinon, j'ai pensé à mettre plusieurs paramètres à la méthode, genre getArrayObj($key, $key_dim2 = NULL, $key_dim3 = NULL, ...).
Ca pourrait ce faire, mais c'est pas très académique, non ?

Il y aurait peut être les fonctions func_num_args() et func_get_args, mais là je ne vois pas trop pour le moment.

Le dernier recourt serait de rendre $arrayObj publique et statique, mais ça m'embête un peu beaucoup.


S'il quelqu'un a une piste
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2010, 11h13   #2
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 691
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 691
Points : 3 258
Points : 3 258
Et bien c'est très simple finalement avec func_num_args() et func_get_args().

Pour le moment j'ai fait très basique, un peu limité à 4 dimensions, mais bon ...
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
    public function getInArrayObj() {
        $num_args = func_num_args();
        $args = func_get_args();
        if (empty($args) || (int)$num_args <= 0) throw new Exception('La méthode '.__METHOD__.' n\'a aucun argument (ou clé) à rechercher.', E_USER_ERROR);
        //
        if ((int)$num_args > 0) {
            switch((int)$num_args) {
                case 1 : return $this->arrayObj[$args[0]];
                break;
                case 2 : return $this->arrayObj[$args[0]][$args[1]];
                break;
                case 3 : return $this->arrayObj[$args[0]][$args[1]][$args[2]];
                break;
                case 4 : return $this->arrayObj[$args[0]][$args[1]][$args[2]][$args[3]];
                break;
            }
        }
    }
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2010, 11h49   #3
Expert Confirmé
 
Avatar de Séb.
 
Inscription : mars 2005
Messages : 2 815
Détails du profil
Informations personnelles :
Âge : 34
Localisation : France

Informations professionnelles :
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mars 2005
Messages : 2 815
Points : 3 440
Points : 3 440
Au final tu veux accéder à un élément de tableau d'une profondeur quelconque en précisant son chemin, non ?

Regarde ça :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function array_access( )
{
    $data = array('Terre' => array('Europe' => array('France', 'Allemagne'),
                                   'Asie' => array('Japon' => 'Tokyo',
                                                   'Chine'))) ;
 
    foreach ( func_get_args( ) as $key ) {
        $data = $data[$key] ;
    }
 
    return $data ;
}
 
header('Content-Type: text/plain') ;
 
print_r(array_access('Terre')) ;
Donne :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array
(
    [Europe] => Array
        (
            [0] => France
            [1] => Allemagne
        )
 
    [Asie] => Array
        (
            [Japon] => Tokyo
            [0] => Chine
        )
 
)
Code :
print_r(array_access('Terre', 'Asie', 'Japon')) ;
Donne :

__________________
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Séb. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2010, 08h38   #4
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 691
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 691
Points : 3 258
Points : 3 258
Citation:
Au final tu veux accéder à un élément de tableau d'une profondeur quelconque en précisant son chemin, non ?
C'est exactement ça.

Ca fonctionne très bien
Le petit bémol que je mettrais, c'est qu'il faille initialiser une variable qui va contenir l'intégralité du tableau $this->arrayObj (ou dans ton exemple $data).
En quelque sorte, j'aurais 2 fois les mêmes données (à une courte période certes).


Il y a détail cependant qui m'interpelle dans la définition de la méthode offsetGet au niveau de la doc, car la méthode existe finalement.
Citation:
mixed ArrayObject::offsetGet ( mixed $index )
J'ai n'ai pas trouver la moindre explication du pourquoi mixed comme type de données en argument ???

A un moment je me suis dis que ça accepterait un tableau genre $argument('Terre', 'Asie', 'Japon') qui supposerait que ça ferait comme dans ton exemple automatiquement.
Mais ça n'accepte pas de tableau visiblement.

Donc le mixed se limiterait soit à une chaine soit un integer.
M'enfin, c'est par déduction.


J'ai fais des recherches sur GG pour tenter de trouver des exemples sur cette méthode offsetGet pour accéder à un tableau à plusieurs dimensions, j'ai franchement rien trouvé.

Mes essais démontrent que cette méthode ArrayObject::offsetGet se limiterait à accéder la 1ère dimension, se que je trouve fort dommage.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2010, 10h03   #5
Modérateur
 
Inscription : septembre 2010
Messages : 7 057
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 057
Points : 8 399
Points : 8 399
Citation:
Envoyé par RunCodePhp Voir le message
Il y a détail cependant qui m'interpelle dans la définition de la méthode offsetGet au niveau de la doc, car la méthode existe finalement.
J'ai n'ai pas trouver la moindre explication du pourquoi mixed comme type de données en argument ???
c'est normal les clés de tableau c'est de type int ou de type string
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2010, 16h15   #6
Modérateur
 
Inscription : septembre 2010
Messages : 7 057
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 057
Points : 8 399
Points : 8 399
et faire comme ca

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class FinderArrayObjectextends ArrayObject
{    
    public function offsetGet($index)
    {
        $offset = parent::offsetGet($index);
 
        if(is_array($offset))
        {
            return new ArrayObject($offset);
        }
 
        return $offset;
    }
}
 
$arr = new FinderArrayObject(array('premier' => array('un' => '1'), 'truc' => 'machin'));
var_dump($arr->offsetGet('premier')->offsetGet('un'));
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2010, 19h54   #7
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 691
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 691
Points : 3 258
Points : 3 258
Citation:
et faire comme ca
Je n'ai peu être pas saisi la manière.

Mais là, il faut faire appel directement à l'Objet $arr pour obtenir la valeur de la 2ème dimension (un).

Ou alors, recréer un autre Objet (FinderArrayObject) avec l'intégralité de l'Objet ArrayObject, etc, etc ... pour au final obtenir 1 élément.
C'est un peu démesuré, non ?


S'il n'y a pas un moyen simple et quasi natif à ArrayObject pour ça, et bien tant pis, il y a quand même les 2 solutions.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2010, 20h11   #8
Expert Confirmé
 
Avatar de Séb.
 
Inscription : mars 2005
Messages : 2 815
Détails du profil
Informations personnelles :
Âge : 34
Localisation : France

Informations professionnelles :
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mars 2005
Messages : 2 815
Points : 3 440
Points : 3 440
Citation:
Mes essais démontrent que cette méthode ArrayObject::offsetGet se limiterait à accéder la 1ère dimension, se que je trouve fort dommage.
Tu peux montrer un exemple ?
__________________
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Séb. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2010, 12h34   #9
Expert Confirmé
 
Avatar de RunCodePhp
 
Inscription : janvier 2010
Messages : 2 691
Détails du profil
Informations personnelles :
Localisation : Réunion

Informations forums :
Inscription : janvier 2010
Messages : 2 691
Points : 3 258
Points : 3 258
Vous avez bien fait d'insister, car je pense que avoir fait fausse route, ou plus familièrement, un peu déliré sur ce coup là.

Je qualifierait ça comme un vrai faux problème.
Si je déclare publique et statique l'Objet/tableau arrayObj, aucun problème vu qu'il sera accessible de l'extérieur.

Donc à l'inverse (pas statique en tout cas, c'est comme ça que je le souhaite), c'est que arrayObj sera ou devra de toute manière être accessible dans la classe, ne serait-ce que par héritage.

Du coup, au lieu de me compliquer la vie comme jusqu'à lors, autant utiliser directement $this->arrayObj, quitte à créer une méthode pour le récupérer intégralement.

Puis ensuite, m'arranger à faire :
Code :
1
2
 
$valeur = $arrayObj[$key_dim_1][$key_dim_2];
En tout cas, je peux faire ainsi, et supprimer cette méthode getInArrayObj() qui ne sert à rien


Je mets fin à ce topic, car j'ai un autre chose sur le feu qui n'est pas loin de me donner mal au crâne.


Merci à vous en tout cas.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]
RunCodePhp est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h10.


 
 
 
 
Partenaires

Hébergement Web