Page 1 sur 1

Fatal error: Cannot use object of type stdClass as array

Posté : 03 sept. 2013, 13:24
par Megadeth
Bonjour,

J'en appelle aux experts car là je ne comprends pas d'où vient mon erreur...

if(isset($objReponse->ReturnListTousTarifs->any["TousTarifs"]->any["Activites"][$i]->any["Produits"][0]->nom)){
...répond bien dans un certain cas mais me renvoie
Fatal error: Cannot use object of type stdClass as array
dans un autre cas alors que je gère bien le else...

le print_r en question donne ceci :

Code : Tout sélectionner

[any] => Array ( [Produits] => Array ( [0] => stdClass Object ( [nom] => PELUCHE
et dans l'autre cas la structure est :

Code : Tout sélectionner

[any] => Array ( [Produits] => stdClass Object ( [nom] => POUPEE
Si je fais ceci :
echo "<h5>".$objReponse->ReturnListTousTarifs->any["TousTarifs"]->any["Activites"][1]->any["Produits"]->nom."</h5>";// ça m'affiche bien poupée...	
d'où mon étonnement...

Merci de votre aide

Mega
;)

Re: Fatal error: Cannot use object of type stdClass as array

Posté : 03 sept. 2013, 13:28
par xTG
Tu tentes d'accéder à l'index 0 dans ton isset alors que tu as un cas où justement ce n'est pas un array mais directement l'objet.
Utilises plutôt ce test :
if( is_array($objReponse->ReturnListTousTarifs->any["TousTarifs"]->any["Activites"][$i]->any["Produits"]) )
Avant de faire ton isset sur l'élément qui t'intéresse.

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 14:22
par Megadeth
Bonjour xTG,

aide PRÉCIEUSE comme toujours.

Je pensais que le fait de faire un isset d'une "chaine" qui n'existait pas, c'était implicite mais visiblement non.

is_array marche du feu de dieu !!!! =D>

J'te paie un coup virtuel à défaut d'un coup physique :boire9:

T'es dans quel coin ?

Mega
;)

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 15:14
par xTG
Si jamais tu passes du côté de la Maine et Loire tu m'en devras un du coup. ;)

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 15:50
par Megadeth
Assurément, je n'y manquerai pas.

Maintenant je vais te poser une ultime question pour savoir comment toi tu gères tes dev.

J'ai une page affiche.php qui instancie un objet et appelle une fonction du type
$monobjet = new monobjet;
derrière ça j'appelle la fonction qui me renvoie une série de valeurs
echo $monobjet ->getToto(1);

getToto renvoie à ma page de classe qui a une fonction getToto...

Si je fais ça, m'oblige à gérer ma mise en page dans ma fonction hors je crois que ce n'est pas trop la bonne démarche (arrête moi si je me trompe)

Que dois-je faire pour tout gérer depuis ma page affiche.php sachant que mes echo sont dans ma page de classe. Tu comprends mon "souci" ?

Je suis assez novice en objet comme tu peux voir...

Mega
;)

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 16:06
par xTG
Ta problématique si je comprends bien c'est de faire du MVC ?

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 16:28
par moogli
salut,

Il est possible de faire de l'affichage dans une classe si elle ne sert qu'a cela.

ceci dit généralement l'affichage se fait sur la page (soit avec du code php, mais pas de code métier, juste la gestion de l'affichage).
tu peux regarder les systèmes de template par exemple.

par exemple
<?php
$pdo = new PDO('...');
$gensDao = new GensDao($pdo);

$listGens = $gensDao->getList();
// listeGens est un tableau d'objet "Gens"
?>
<table>
    <thead>
    <tr>
        <th>Nom</th>
        <th>Pr&eacute;nom</th>
        <th>E-mail</th>
        <th>Etc</th>
    </tr>
    </thead>
    <tfoot>
    <tr>
        <td colspan="4">&nbsp;</td>
    </tr>
    </tfoot>
    <tbody>
    <?php
    $i = 0;
    $cssPaire = 'paire';
    $cssImpaire = 'impaire';
    foreach ($listGens as $gens) {
        if ($i % 2 == 0) {
            $css = $cssPaire;
        } else {
            $css = $cssImpaire;
        }
        echo '<tr class="' . $css . '">
        <td>' . $gens->getNom() . '</td>
        <td>' . $gens->getPrenom() . '</td>
        <td>' . $gens->getEmail() . '</td>
        <td>&nbsp;</td>
        </tr>';
    }
    ?>
    </tbody>
</table>
La classe GensDao contient l'accès aux données, on affiche ce que l'on nous retroune.

Mais tu peux très bien mettre la génération du code html (donc dans une variable) dans une méthode d'une classe et dans la page html faire un simple
<?php
echo $classeFront->getTableGens();
?>
la méthode getTableGens() contient le code que j'ai utilisé plus haut sauf qu'il n'y a pas de echo, juste l'utilisation d'une variable.


@+

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 16:35
par Megadeth
Kesako ? Peut être, je sais pas ^^

En fait via un webservice j'appelle un tas d'infos et ramène des noms de jouets, des prix mais tout via une seule et même fonction comme tu as pu voir dans mon print_r.

Ma question était de savoir comment je pouvais ou plutôt devais organiser mon appel, mon code pour mêler infos et mise en page html ?

dois-je mettre les <ul><li>...dans les echo de ma fonction de mon objet classe ou puis-je faire autrement depuis la page affiche.php ?

J'espère être plus clair :)

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 16:49
par Megadeth
J'ai vu ta/vos réponses.

Ca veut dire créer une fonction pour récupérer juste le nom du jouet, une fonction pour récupérer juste le prix...ou la fonction peut cracher de la mise en page ?

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 03 sept. 2013, 16:51
par moogli
l'organisation, peux passer par un mvc comme l'indiquer xTG.

Cela relève de la modélisation de l'application, dont le mvc fait partie (et la modélisation est a faire en premier lieu avant de coder ;))

l'exemple que je t'ai montré c'est le pattern DAO (pour data access object).
Ce motif n'est pas lié à l'accès aux sgbd mais peux être utilisé quelque soit l'origine de la donnée.

donc une dao pour l'accès au webservice est correct.
Mais une DAO ne fait pas d'affichage, devrait te retourner le table (ou l'objet) qui est fournit par $objReponse->ReturnListTousTarifs->any["TousTarifs"]->any["Activites"][$i]->any["Produits"]

(en gros la dernière ligne de la méthode pourrait être return $objReponse->ReturnListTousTarifs->any["TousTarifs"]->any["Activites"][$i]->any["Produits"]), mais il serait préférable de t'assurer de retourner un tableau pour éviter les problèmes ;) ).

du coup dans la partie affichage tu aura un truc du genre $tablo = $maDaoJouet->getList(); et tu travail sur $tablo comme dans on exemple ;)

@+

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 04 sept. 2013, 09:40
par Megadeth
Re,

Bah imaginez un webservice qui vous ramène tous les modèles de motos que vous vendez avec son cylindré, son prix, son année de mise en circulation...et que vous devez afficher le tout sur une page (affiche.php) vous vous y prendriez comment ? Vous feriez des getTruc de chaque caractéristique ? Sachant que pour le coup vous rappelez le même webservice puisque l'info est déjà dans le premier appel ?

Je suis intéressé par vos approches et réflexions et c'est vrai que phpFrance est génial pour ça !

Mega
;)

Re: [RESOLU] Fatal error: Cannot use object of type stdClass

Posté : 04 sept. 2013, 11:11
par moogli
Oui, cela s'appel des assesseurs lorsque l'on parle de méthodes retournant ou permettant la modification d'un attribut d'un objet.

Il faut différencier les objets.
Ceux qui représente les données, parfois appelé entités, en java ce sont des pojo (traduit en français de bon vieux objet java, en php cela ferais des 'popo' :mrgreen: ).
Par exemple du aurais une entité jouet avec les propriétés nom, description, prix (et tous le reste utile).
Toutes les propriétés sont par défaut privées (protégée si pense a l'héritage ;) ). Pour les utiliser on utilise des assesseurs.
Par convention getNom(), setNom() etc.
Cette objet représente un jouet.

Ensuite, il y a les objets métiers. Ce sont les objets qui implémente les règles de gestion. par exemple : un jouet a obligatoirement un nom, un prix et une description le reste est obligatoire. C'est une règle de gestion et elle codée dans un objet métier.

Les objets DAO, dont j'ai déjà parlé avant.
Ces objets permettent de masquer l'accès aux données (si demain l'info vient d'une bdd ou d'un fichier tu modifie juste le contenu des méthodes et ne modifie pas le reste du code qui doit rester valide ;) ).
Donc ta DAO jouet, avec une méthode getList() retourne un tableau de jouet.
Sur l'affichage tu fait simplement appel à ton objet Dao pour obtenir la liste et l'afficher, la DAO n'a pas pas besoin de savoir ce que tu en fait elle te fournit juste la liste ;)

@+