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

PHP & Base de données Discussion :

[php et xquery] Fatal error: Call to a member function children() on a non-object


Sujet :

PHP & Base de données

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut [php et xquery] Fatal error: Call to a member function children() on a non-object
    Bonjour,

    Je travaille sur une base de données Exist (où sont donc stockés des fichiers .xml).


    J'ai une page .php dans laquelle je souhaite, quand un utilisateur poste un commentaire :
    • ajouter le commentaire dans la base
    • mettre à jour le nombre de points de l'utilisateur (quand il poste un commentaire, on lui donne 5 points).



    Mes deux requêtes Xquery fonctionnent bien séparément. (si je commente la 2ème requête, l'ajout de commentaire dans la base fonctionne ; si je commente la 1ère requête, la mise à jour du nombre de points marche).

    Mon problème : Quand je veux exécuter mes 2 requêtes, la 2ème n'est pas exécutée et j'ai une fatal error :
    Fatal error: Call to a member function children() on a non-object in C:\wamp\www\Macaronissime\Scripts\Utilisateur\ficheProduit.php on line 89

    La ligne 89 est :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    $nbPoints = $object2->children()->points + 5;

    Mon code PHP :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    /* si l'utilisateur a poste un commentaire */
    if(isset($_POST['commentaire'])) {
        $pseudo = $_POST['pseudo'];
        $commentaire = $_POST['commentaire'];
     
     
        /* on insere le commentaire */
        /* requete qui recherche l'id max parmis les commentaires */
        $query0 = '<id><idMax>{let $idComm := document("macaronissime/base.xml")//commentaire/@idComm return max($idComm)}</idMax></id>';
        $result0 = $db->xquery($query0);
        $object0 = simplexml_load_string($result0["XML"]);
     
        /* on incremente l'id */
        $idComm = $object0->children()->idMax + 1;
     
        /* on insere le commentaire en BD */
        $query1 = 'for $commentaires in document("macaronissime/base.xml")/macaronissime/commentaires
            return update insert
            <commentaire idComm=\''.$idComm.'\'>
            <categorie>'.$idCategorie.'</categorie>
            <pseudo>'.$pseudo.'</pseudo>
            <contenu>'.$commentaire.'</contenu>
            </commentaire> into $commentaires';
        $db->xquery($query1);
     
     
        /* on augmente de 5 points l'utilisateur a chaque commentaire */
        /* requete qui recherche le nombre de points de l'utilisateur */
        $query2 = 'for $clients in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'" ]
              return <nombre>{$clients/points}</nombre>';
        $result2 = $db->xquery($query2);
        $object2 = simplexml_load_string($result2["XML"]);
     
     
        /* on augmente de 5 points */
     $nbPoints = $object2->children()->points + 5;
     
        /* on met a jour le nombre de points de l'utilisateur */
        $b = 'for $p in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'"]/points
                    return update replace $p with <points>'.$nbPoints.'</points>';
        $db->xquery($b);
     
    }

    Quelqu'un aurait une idée ? Cela fait plusieurs jours que je recherche, et je dois avouer que je sèche ..

    Merci d'avance

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    772
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2004
    Messages : 772
    Points : 872
    Points
    872
    Par défaut
    Il semble que la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     $object2 = simplexml_load_string($result2["XML"]);
    ne retourne pas un objet XML, et donc que $result2["XML"] ne soit pas un un fichier xml valide...

    As-tu testé le retour de $query2 ?
    • Mon blog PHP : http://blog.alterphp.com
    • "Peace cannot be kept by force, it can only be achieved by Understanding" -- Albert Einstein

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Il me semble que le problème ne vient pas de la requête xquery en elle-même, car si je commente ma 1ère requête en faisant : "//$db->xquery($query1);", alors la 2ème requête ne retourne pas la fatal error.

    J'ai essayé de tester le retour en faisant un count juste après la ligne que tu cites :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        $object2 = simplexml_load_string($result2["XML"]);
        echo "taille : ".count($object2);
    Et cela m'affiche "taille : 1" donc il y a un retour ..


    Et quand j'exécute ma requête xquery dans l'interface de ma base de données Exist, le résultat est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <nombre>
    <points>10</points>
    </nombre>

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    772
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2004
    Messages : 772
    Points : 872
    Points
    872
    Par défaut
    et un var_dump($object2) ?
    • Mon blog PHP : http://blog.alterphp.com
    • "Peace cannot be kept by force, it can only be achieved by Understanding" -- Albert Einstein

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Là, cela m'affiche "bool(false)"

    EDIT : Tandis que lorsque je commente ma 1ère requete pour ne pas l'exécuter,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo var_dump($object2);
    affiche : object(SimpleXMLElement)#3 (1) { ["points"]=> string(2) "10" }
    ("10" etant le nombre de points)

  6. #6
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    SimpleXML ne fait que des requêtes de sélection, tourne toi vers DOMXpath avec la méthode evaluate

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Je n'utilise SimpleXML que pour des requêtes de sélection pourtant, je ne vois pas ce que tu veux dire ?

    Je vais regarder DOMXpath.

  8. #8
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par torfinn Voir le message
    Je n'utilise SimpleXML que pour des requêtes de sélection pourtant, je ne vois pas ce que tu veux dire ?

    Je vais regarder DOMXpath.
    non pardon c'est ton xquery qui m'a perturbé, pour ton probleme ton XML n'as pas d'enfant puisque nombre est considérer comme le root c'est donc simplement :

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par stealth35 Voir le message
    J'ai fait ce que tu m'as dit, et j'ai toujours la même error fatal : Notice: Trying to get property of non-object in C:\wamp\www\Macaronissime\Scripts\Utilisateur\ficheProduit.php on line 89


    Ce que je n'arrive pas à comprendre, c'est que si je commente cette ligne (qui insère le commentaire)
    alors la requête suivante (ajout de 5 points) fonctionne et je n'ai plus la fatal error
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        $nbPoints = $object2->points + 5;
     
        /* on met a jour le nombre de points de l'utilisateur */
        $b = 'for $p in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'"]/points
                    return update replace $p with <points>'.$nbPoints.'</points>';
        $db->xquery($b);

    Comme si il fallait nettoyer quelque chose entre les 2 requêtes ..

  10. #10
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    a toi de jouer avec les var_dump voir ce qui se passe, xquery ca vient d'où ? ton niveau d'erreur est bien au maximum ?

  11. #11
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Le code suivant (où la 1ère requête marche mais pas la 2ème)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        $db->xquery($query1);
     
     
        /* on augmente de 5 points l'utilisateur a chaque commentaire */
        /* requete qui recherche le nombre de points de l'utilisateur */
        $query2 = 'for $clients in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'" ]
              return <nombre>{$clients/points}</nombre>';
        $result2 = $db->xquery($query2);
        $object2 = simplexml_load_string($result2["XML"]);
        echo var_dump($query2).'<br/>';
        echo var_dump($result2).'<br/>';
        echo var_dump($object2).'<br/>';
    affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    string(140) "for $clients in document("macaronissime/base.xml")/macaronissime//client[@idClient="1" ] return {$clients/points}"
    bool(false)
    bool(false) 
     
    Notice: Trying to get property of non-object in C:\wamp\www\Macaronissime\Scripts\Utilisateur\ficheProduit.php on line 89

    Tandis que dans le code suivant où je ne fais que mettre en commentaire la 1ère requete; la 2ème requête marche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        //$db->xquery($query1);
     
     
        /* on augmente de 5 points l'utilisateur a chaque commentaire */
        /* requete qui recherche le nombre de points de l'utilisateur */
        $query2 = 'for $clients in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'" ]
              return <nombre>{$clients/points}</nombre>';
        $result2 = $db->xquery($query2);
        $object2 = simplexml_load_string($result2["XML"]);
        echo var_dump($query2).'<br/>';
        echo var_dump($result2).'<br/>';
        echo var_dump($object2).'<br/>';
    affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    string(140) "for $clients in document("macaronissime/base.xml")/macaronissime//client[@idClient="1" ] return {$clients/points}"
    array(4) { ["HITS"]=> int(1) ["COLLECTIONS"]=> object(stdClass)#7 (0) { } ["QUERY_TIME"]=> int(2) ["XML"]=> string(42) " 35 " }
    object(SimpleXMLElement)#3 (1) { ["points"]=> string(2) "35" }

    Donc effectivement on s'apperçoit, dans le cas où je veux exécuter mes 2 requêtes (1er cas que je me montre ci-dessus) que la 2ème requête ($db->xquery($query2)) ne retourne pas d'array .. mais pourquoi ?

  12. #12
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par stealth35 Voir le message
    xquery ca vient d'où ? ton niveau d'erreur est bien au maximum ?

  13. #13
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Ah oui ! Que veux-tu savoir par "xquery ça vient d'où ?" ?
    Et le niveau d'erreur tu parles de celui de serveur ? (j'utilise wamp) Si oui comment le modifier ?

  14. #14
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par torfinn Voir le message
    Ah oui ! Que veux-tu savoir par "xquery ça vient d'où ?" ?
    Et le niveau d'erreur tu parles de celui de serveur ? (j'utilise wamp) Si oui comment le modifier ?

    la méthode xquery vient de quelle librairie ?

    pour le niveau d'erreur je parle du error_reporting qui dois etre a E_ALL | E_STRICT, a changer dans ton php.ini ou au debut de ton script fait :

  15. #15
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Visiblement le niveau d'erreur est bien au maximum vu qu'en mettant error_reporting(-1); en début du script, j'ai exactement le même message :
    Notice: Trying to get property of non-object in C:\wamp\www\Macaronissime\Scripts\Utilisateur\ficheProduit.php on line 89
    Quand à xquery, la méthode vient de la libraire eXist.php
    Fichiers attachés Fichiers attachés

  16. #16
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    y'a peu etre une reference qui traine, apres faudrais voir avec l'auteur de la classe, mais je comprend pas ta requete :

    tu recois du XML, tu fais un xquery pour transformer ton XML et tu le remet dans SimpleXML pour compter le nombre de noeuds ?
    pourquoi ne pas compter directement le nombre de noeuds dans le XML d'origine,
    et comme derrière c'est du SOAP doit bien y'avoir une fonctions qui fait ton calcule dans l'API ?
    quelle est le but complet de ton code ?

  17. #17
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Le but de mon complet de mon code que j'ai mis dans mon 1er post
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    /* si l'utilisateur a poste un commentaire */
    if(isset($_POST['commentaire'])) {
        $pseudo = $_POST['pseudo'];
        $commentaire = $_POST['commentaire'];
     
     
        /* on insere le commentaire */
        /* requete qui recherche l'id max parmis les commentaires */
        $query0 = '<id><idMax>{let $idComm := document("macaronissime/base.xml")//commentaire/@idComm return max($idComm)}</idMax></id>';
        $result0 = $db->xquery($query0);
        $object0 = simplexml_load_string($result0["XML"]);
     
        /* on incremente l'id */
        $idComm = $object0->children()->idMax + 1;
     
        /* on insere le commentaire en BD */
        $query1 = 'for $commentaires in document("macaronissime/base.xml")/macaronissime/commentaires
            return update insert
            <commentaire idComm=\''.$idComm.'\'>
            <categorie>'.$idCategorie.'</categorie>
            <pseudo>'.$pseudo.'</pseudo>
            <contenu>'.$commentaire.'</contenu>
            </commentaire> into $commentaires';
        $db->xquery($query1);
     
     
        /* on augmente de 5 points l'utilisateur a chaque commentaire */
        /* requete qui recherche le nombre de points de l'utilisateur */
        $query2 = 'for $clients in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'" ]
              return <nombre>{$clients/points}</nombre>';
        $result2 = $db->xquery($query2);
        $object2 = simplexml_load_string($result2["XML"]);
     
     
        /* on augmente de 5 points */
     $nbPoints = $object2->children()->points + 5;
     
        /* on met a jour le nombre de points de l'utilisateur */
        $b = 'for $p in document("macaronissime/base.xml")/macaronissime//client[@idClient="'.$idClient.'"]/points
                    return update replace $p with <points>'.$nbPoints.'</points>';
        $db->xquery($b);
     
    }
    • insérer un commentaire entré par un utilisateur
    • mettre à jour le nombre de points de cet utilisateur en l'augmentant de 5 points.

    $query0 : recherche l'id du dernier commentaire
    $query1 : insere le commentaire (avec id+1)
    $query2 : recherche le nombre de points de l'utilisateur qui insère le commentaire
    $b : met à jour le nombre de points de l'utilisateur (+5)


    Résumé du problème :
    Si je commente $query1, alors $b est exécuté (l'utilisateur a donc 5 points de plus, mais le commentaire n'est pas inséré)
    Si je ne commente pas $query1, alors j'ai l'erreur (le commentaire est inséré, mais le nombre de points de l'uilisateur n'est pas mis à jour) :
    Fatal error: Call to a member function children() on a non-object in C:\wamp\www\Macaronissime\Scripts\Utilisateur\ficheProduit.php on line 89
    à la ligne :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    $nbPoints = $object2->children()->points + 5;



    On peut surement réduire le nombre de requêtes, mais c'est des requêtes de base .. pourquoi n'arriverait-on pas le faire (alors qu'en SQL cela me prendrait 2 minutes) ?

  18. #18
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    avec juste SimpleXML/DOMDocument tu dois pouvoir le faire, t'as un petit exemple de ta base ou on peu faire des tests

  19. #19
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 13
    Points : 1
    Points
    1
    Par défaut
    Bien sûr, j'utilise eXist

    EDIT :
    Sachant que la connection à la base se fait dans mon index.php :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        include ('Scripts/Include/eXist.php');
     
        $db = new eXist();
        /* Connexion a la base eXist */
        $db->connect() or die ($db->getError());
    Et que mon script est inclu dans l'index.php.
    Fichiers attachés Fichiers attachés

  20. #20
    Expert éminent sénior

    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
    Points : 10 726
    Points
    10 726
    Par défaut
    juste comme ca (pas besion de eXist):
    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
    20
    $file    = 'base.xml';
    $pseudo  = 'meldu91';
    $contenu = 'test';
     
    $xml = simplexml_load_file($file);
     
    $query  = $xml->xpath("//clients/client/pseudo[text() = '$pseudo']/..");
    $client = $query[0];
     
    $query  = $xml->xpath("//commentaires/commentaire/pseudo[text() = '$pseudo']");
    $number = count($query);
     
    $client->points += 5;
     
    $commentaire = $xml->commentaires->addChild('commentaire');
    $commentaire->addAttribute('idComm', ++$number);
    $commentaire->addChild('pseudo', $pseudo);
    $commentaire->addChild('contenu', $contenu);
     
    echo $xml->asXML();

Discussions similaires

  1. [PDO] Fatal error: Call to a member function fetch() on a non-object
    Par blopjerem dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 03/12/2009, 10h53
  2. Réponses: 4
    Dernier message: 07/10/2009, 11h53
  3. Réponses: 4
    Dernier message: 02/10/2009, 10h12
  4. [PDO] Fatal error: Call to a member function setFetchMode() on a non-object in
    Par tores20 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 28/07/2009, 23h04
  5. [PHP 5.2] Fatal error: Call to a member function bindValue() on a non-object
    Par TeraD dans le forum Langage
    Réponses: 4
    Dernier message: 23/06/2009, 00h20

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