IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

ArrayObject à plusieurs dimensions : Accéder via une méthode [PHP 5.3]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $arrayObj = new ArrayObject(array('premier' => 'un'));
    echo $arrayObj['param'];
    // Ou
    echo $arrayObj->offsetGet('premier');
    A 2 dimensions aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
                }
            }
        }

  3. #3
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 315
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 315
    Billets dans le blog
    17
    Par défaut
    Au final tu veux accéder à un élément de tableau d'une profondeur quelconque en précisant son chemin, non ?

    Regarde ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    print_r(array_access('Terre', 'Asie', 'Japon')) ;
    Donne :


  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    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.
    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.

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    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

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    et faire comme ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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'));

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/07/2011, 14h20
  2. draggable: ne fonctionne via une méthode POST
    Par nims dans le forum jQuery
    Réponses: 8
    Dernier message: 30/11/2009, 11h51
  3. Réponses: 5
    Dernier message: 24/03/2009, 10h20
  4. [MySQL] Plusieurs paramètres dynamiques dans une méthode ?
    Par artotal dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 11/07/2008, 15h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo