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

Mammouth du PHP | 737 Messages

03 sept. 2013, 13:24

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
;)
Dyslexics are teople poo

ViPHP
xTG
ViPHP | 7331 Messages

03 sept. 2013, 13:28

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.

Mammouth du PHP | 737 Messages

03 sept. 2013, 14:22

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
;)
Dyslexics are teople poo

ViPHP
xTG
ViPHP | 7331 Messages

03 sept. 2013, 15:14

Si jamais tu passes du côté de la Maine et Loire tu m'en devras un du coup. ;)

Mammouth du PHP | 737 Messages

03 sept. 2013, 15:50

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
;)
Dyslexics are teople poo

ViPHP
xTG
ViPHP | 7331 Messages

03 sept. 2013, 16:06

Ta problématique si je comprends bien c'est de faire du MVC ?

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

03 sept. 2013, 16:28

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.


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

Mammouth du PHP | 737 Messages

03 sept. 2013, 16:35

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 :)
Dyslexics are teople poo

Mammouth du PHP | 737 Messages

03 sept. 2013, 16:49

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 ?
Dyslexics are teople poo

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

03 sept. 2013, 16:51

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 ;)

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

Mammouth du PHP | 737 Messages

04 sept. 2013, 09:40

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
;)
Dyslexics are teople poo

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

04 sept. 2013, 11:11

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 ;)

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