Accès aux propriétés d'un objet

Eléphanteau du PHP | 44 Messages

03 oct. 2011, 09:10

Bonjour, dans mon application, je transmet un objet à la méthode d'une autre classe, cette méthode doit s'occuper de concaténer les valeurs de cet objet à une chaîne de caractères.

Le problème est que je n'arrive pas à transformer mon objet en chaîne #-o

En gros voici le contenu de mon objet :

Code : Tout sélectionner

Array ( [0] => Articles Object ( [auteur:protected] => admin [auteurId:protected] => 1 [titre:protected] => une histoire de X [contenu:protected] => il était une fois un marchand de foi qui vendait du foie dans la ville de foix § [categorie:protected] => prog [categorieId:protected] => 2 [datePublication:protected] => Array ( [jourNom] => Dimanche [jour] => 02 [moisNom] => novembre [mois] => 10 [année] => 2011 ) etc.... )
[/size]

Maintenant ma fonction devant s'occuper d'ajouter les valeurs de l'objet à ma chaîne.
public function parseValues(array $values)
    {
        foreach( $values as $name => $value )
        {
            if( is_array($value) )
            {
                $this->parseValues($value);
            }
            else
            {
                $this->content.= '<' . $name. '>' . $value . '</' . $name . '>';
            }
        }
    }
Problème, avec ce code, j'ai une erreur
Catchable fatal error: Object of class Articles could not be converted to string in ....
Comment faire pour accéder au valeurs des propriétés de la class ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

03 oct. 2011, 10:47

J'ai du mal à voir d'où vient le paramètre $values ...

Est-ce que tu peux nous montrer comment tu appelles la méthode parseValues() (surtout ce que tu lui passes) et nous donner le message d'erreur complet (y compris la ligne) et à quoi ça correspond dans ta classe.

Si je ne me trompe, tu passes l'objet à la méthode, et c'est pas du tout ce qu'il faut faire ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphanteau du PHP | 44 Messages

03 oct. 2011, 11:47

$values est un array contenant plusieurs instance de ma classe Articles.

Je l’appelle de cette façon dans mon contrôleur d'articles :
$this->application->xml()->parseValues($articles)
Bon j'ai vu que l'on pouvait se servir de get_objet_vars(), mais le problème il faut que les propriétés de la class soient public, donc je ne peux m'en servir extérieurement à ma classe puisqu'ils sont protégés ...
Un typage des objets en array fait bizarrement planter apache :lol: , enfin il réinitialise la connexion et ensuite il tourne en boucle dans le vide.

La seule solution que j'ai trouvé est d'ajouter une méthode à ma classe articles pour me retourner les propriétés sous forme d'array
public function getAttributes()
{
      return get_object_vars($this);
}
Ainsi je l'utiliserais
 $this->application->xml()->parseValues($articles->getAttributes())
C'est pas la panacée, mais j'ai rien trouvé de mieux.

Eléphant du PHP | 171 Messages

04 oct. 2011, 17:19

En fait, ton erreur est du à ta condition avec le "is_array".
Donc à chaque fois qu'il itère ton tableau, il effectue la condition mais un objet n'étant pas un tableau, il effectue le else et il essaye donc de traiter ton objet comme une chaine. D’où l'erreur :
Catchable fatal error: Object of class Articles could not be converted to string in ...
Utilise plutôt is_object et même au mieux : instanceof qui est idéal dans ton cas puisque le tableau d'objet ne contiendra que des instances de Article. Je te laisse te référer à la documentation pour son utilisation.

Ensuite pour qu'un objet puisse être itéré comme un tableau tu as le choix :
Implémenté get_object_vars(); directement dans ta méthode parsesValues() ou rendre ton objet itèrable si je me rappelle bien avec l'interface Iterable.
Modifié en dernier par Skw33d le 04 oct. 2011, 20:29, modifié 1 fois.
Le bon jugement s'apprend par l'expérience qui s'acquiert en partie par le mauvais jugement.

Eléphanteau du PHP | 44 Messages

04 oct. 2011, 18:41

Non, je ne peux utiliser instanceof puisque laméthode de cette classe pourra recevoir différents types d'objets.

Et is_object, mouais ce n'est pas ça qui va résoudre le problème, à la limite juste pour un contrôle draconien, mis à part ça, rien d'autres.

Je crois que j'ai mal dû me faire comprendre.

En gros :

Une class A qui génère plusieurs objet d'une classe B (dont les propriétés sont protected) dans un array, cette class A passe ensuite cet array à une méthode d'une class C, C::methode(array(object B, object B, etc..))

Maintenant dans cette méthode de la class C donc, je parcours l'array contenant les objets, et il faut que je puisse accéder aux valeurs des propriétés de chaque objet, pour les affecter à un string.

Enfin, je suis en train de revoir ce fonctionnement, puisqu'il est un peu contraignant.

Par contre ouais je pourrais me servir d'interface, mais je pige pas encore trop le principe.

Merci de ta réponse :P

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 oct. 2011, 00:44

yop,

pourquoi ne pas créer une méthode dans B qui te fournit toute les infos ? dans C un foreach simple qui récupère les infos a l'aide d'une seule méthode ?


@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 44 Messages

05 oct. 2011, 06:03

C'est ce que j'ai fait avec get_object_vars($this)

Mais je trouve pas ça très propre :?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 oct. 2011, 16:42

hum au vu de l'erreur que tu indique a tu pensé à la méthode magique __toString()

pour ce qui est des interfaces elles permettent "d'obliger" à implémenter une méthode dans les classes qui implémentent l'interface ou celle qui en dérive.
en gros une interface avec une méthode toto() impose un "function toto()" dans la classe.

tu peux voir aussi du coté des classes abstraites

l'utilisation d'une interface va te permettre (puisse qu'a priori les objets ne seront pas tous de type B) d'avoir des objets différents de type, D, E, X ou Z qui auront tous une méthode te permettant de récupérer les infos que tu souhaite (par exemple toString()).

je ne vois pas trop le but de la chose, mais je pense que l'interface et implementer cette interface sur tout les objets est une bonne solution (surtout que tu semble vouloir générer du xml et la tu pourrait utiliser cette méthode pour générer un arbre xml de la classe (pourquoi pas en utilisant la classe reflection).

voir aussi :
http://fr2.php.net/manual/fr/language.o ... ations.php


@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 44 Messages

05 oct. 2011, 17:41

En effet je l'avais oublié cette méthode magique, à part __construct() et __destruct() les autres je m'en sers pas :mrgreen:

J'avais donc bien compris le principe des interfaces, on pourrait la comparer avec la dtd d'un document xml qui oblige à suivre un modèle.

J'utilise déjà des classes abstraites, mais dans ce cas, elle ne me sont d'aucun secours.

La reflection, j'ai pas saisi à quoi ça pourrait me servir ici, c'est un peu un truc pour générer un schéma non ? Une sorte d'uml simplifié, donc pour une doc sur l'application éventuellement, c'est pas ça ?

De toute façon, j'ai revu le tout et je n'ai plus besoin de passer l'objet en argument, je génère directement le xml depuis la class en suivant un model établi dans un fichier, donc une méthode qui devra être implémentée dans toutes les classes de mêmes types (chacun ayant son fichier modèle), là une interface sera donc en effet utile.

Merci :wink: