IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> appel d'une méthode sur un objet php créé avec une chaine json
Options
toluol
posté 25 Oct 2015, 13:55
Message #1


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Bonjour,

j'ai une question dont la résolution m'est très obscure :

Ayant récupéré une chaine json, j'ai pu créer un objet php selon une Class que j'ai trouvé :
Code
class JSONObject {
    public function __construct($json = false) {
        if ($json) $this->set(json_decode($json, true));
    }

    public function set($data) {
        foreach ($data AS $key => $value) {
            if (is_array($value)) {
                $sub = new JSONObject;
                $sub->set($value);
                $value = $sub;
            }
            $this->{$key} = $value;
        }
    }
}


Ensuite, malheureusement, je n'arrive plus à utiliser les méthodes de mes classes sur ce nouvel objet (qui a pourtant la même structure).
Mes méthodes sont pourtant "public". N'arrive-t-on qu'à modifier les objets par les méthodes d'une classe qui a créé ce même objet ?

En gros :
Code
$json = '{"html":"ma première valeur"}';
$obj = new JSONObject($json);
echo $obj->html; //retourne ma première valeur
//Jusqu'ici tout fonctionne, mais si j'appelle la méthode :
$obj->setNewHtml('ma deuxième valeur');
// j'obtiens : Fatal error: Call to undefined method JSONObject::setNewHtml()


Une solution, serait-elle de clôner les valeurs de l'objet json sur un objet de ma classe ?
Merci pour toute réponse.

Go to the top of the page
 
+Quote Post
Jaypee
posté 25 Oct 2015, 19:35
Message #2


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Tu n'es pas très clair sur ce que tu cherches à obtenir:
- Veux-tu un autre objet JSON avec un champ newHTML ?
- Veux-tu changer la valeur de l'HTML du premier objet ?
- Veux-tu ajouter un deuxième champ newHTML au premier objet ?

Avant-même que d'écrire du code, il faut savoir lire et comprendre le code existant:
- Le symbole setNewHTML qui n'a jamais été déclaré ou défini, comment serait-il disponible à l'emploi ?

Si on lit le code on peut comprendre que la syntaxe possible pour modifier un objet existant est :
$obj->set(clé, valeur);

Une clé, ce peut être "html", "titre"

C'est ce qu'on peut lire dans le code de la classe.

J-P
Go to the top of the page
 
+Quote Post
toluol
posté 26 Oct 2015, 01:01
Message #3


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Tout d'abord, merci pour ta réponse. Et désolé si je ne me suis pas exprimé assez clairement.

Je comprends bien le code que j'ai écrit, mais il est vrai que je n'avais pas tout mis (notamment les include de ma classe) par souci de sobriété, mais il est vrai que la demande, du coup, pouvait être un peu "fouilli" ! laugh.gif

Je vais donc reformuler de manière linéaire avec des commentaires dans mon code...

Code
//myClass.class.php *************************************************

//voici une classe basique qui ne sert qu'à enregistrer un nombre et à faire des calculs...
// ça ne sert quasi à rien, mais c'est pour l'exemple d'accès aux méthodes
class MyClass{
    private $number = null;
    public function __construct($number){$this->number = $number;}
    public function getNumber(){return $this->number;}
    public function setNumber($number){$this->number = $number;}
    public function multiply(){return $this->number*$this->number;}
    public function divide(){return $this->number/$this->number;}    
}

//fichier1.php *************************************************

//création premier objet
include_once('myClass.class.php ');
$obj = new MyClass(8); //on enregistre un premier nombre
echo $obj->getNumber(); //affiche : 8
$obj->setNumber(5); //on change de nombre
echo $obj->getNumber(); //affiche : 5
echo $obj->multiply(); //on décide d'utiliser la méthode multipliy, il affiche : 25

//JSONObject.class.php *************************************************

//voici ma classe qui sert à transformer une chaine json en objet php
class JSONObject {
    public function __construct($json = false) {
        if ($json) $this->set(json_decode($json, true));
    }
    public function set($data) {
        foreach ($data AS $key => $value) {
            if (is_array($value)) {
                $sub = new JSONObject;
                $sub->set($value);
                $value = $sub;
            }
            $this->{$key} = $value;
        }
    }
}

//fichier2.php (ajax) *************************************************

include_once('myClass.class.php ');
include_once('JSONObject.class.php ');
//dans ce nouveau fichier php, je récupère d'une chaine json (issu de javascript)
// je n'ai plus accès au premier objet "$obj" issu de fichier1.php
// mais j'ai son "image" au format json
//$json = stripslashes($_POST['json']); //echo $json retournerai : {"number":25}
$json = '{"number":25}'; //juste pour continuer l'exemple sans la réception javascript
$obj2 = new JSONObject($json);
echo $obj2->number; //retourne : 25

//... jusque là, tout va bien... sauf que lorsque je souhaite utiliser myClass sur ce nouvel objet
echo $obj2->divide(); // ça bug... ! j'obtiens : Fatal error: Call to undefined method JSONObject::divide()
//en même temps, je comprends que c'est logique puisque ce n'est pas un objet créé par myClass, mais par JSONObject...
//Comment néanmoins utiliser mes méthodes sur $obj2 ?


C'est cette question qui me tarabiscuite l'esprit... tongue.gif huh.gif
Je suis aller chercher des idées du coté du clonage d'objet dans le manuel php, mais je n'ai pas compris ce que je pouvais en faire... Puisque, étant dans un fichier ajax, donc un 2e fichier php, je ne peux pas faire un clone d'un objet que je n'ai pas... (Euh... On me suit toujours là ? :usure:)

En fait, le plus logique serait de pouvoir créer un nouvel objet issu de myClass et de lui attribuer toutes les valeurs json...
Un peu comme ça :

$obj2 = new MyClass(null); //recrée nouvel objet
$obj2->magicFonction_ConvertJson($json); //clone les valeurs
echo $obj2->getNumber(); //retourne 25
echo $obj2->divide(); //retourne 5

... sauf que cette fonction "magicFonction_ConvertJson", ben euh...

Ce message a été modifié par toluol - 26 Oct 2015, 01:11.
Go to the top of the page
 
+Quote Post
Jaypee
posté 26 Oct 2015, 08:09
Message #4


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Ton erreur provient du manque d'expressivité, du manque de style !

Donne un vrai nom à ta classe, par exemple, Number.

Et tes objets, n'inclut pas le mot objet dans leur nom, ce sont tous des objets,
Appelle-les:
$num1 ou $json1
ou au pire tu utilises l'initiale: $oNum1, $oJson1

Tu ne seras pas tenté ensuite de faire $json1->divide() qui n'a pas de sens et ça se voit.

Parlant de style, je ne vois pas où les méthodes de la classe te mènent.
J'aurais bien imaginé:
$num1 = new Number(3.0);
$num2 = $num1->multiply(4.0);
etc...

Là, maintenant, je te préviens ça devient un peu subtil: Imagine qu'au lieu de retourner un résultat numérique (au sens type primitif, int, float...) tu retournes l'objet lui-même: return $this !
Quel intérêt ? Pouvoir écrire ceci:

$num3 = new Number(2.0)->multiply(3.0)->divide(5.0);

Tu pourrais ainsi appeler tes méthodes en cascade. Ce style est devenu classique sous le nom interface fluide et permet de se créer une sorte de mini-langage:
$voiture = new Voiture()->avecCylindrée(1600)->avecCouleur("vert")->avecCarburant("GPL")->avecPlaces(5);
à comparer avec:
$auto = new Voiture(5, "GPL", 1600, "vert"); // La position est importante, elle détermine le sens, si tu inverses 5 et 1600 tu auras des soucis...

Ensuite réfléchis à ce qui se passe. Tu n'as créé qu'un objet $num1, que tu as transformé, sur lequel tu as placé une seconde "laisse" $num2, mais il n'y a qu'un seul et même objet au bout des deux laisses $num1 et $num2.
Alors là oui tu peux décider de cloner l'objet original avant de le transformer, mais attention, tu dois penser à ajouter un destructeur à ta classe, et à faire des unset() là où l'objet ne sert plus.

Ce n'était qu'une discussion sur le style et l'expressivité qui peut éviter des erreurs. Tu en fais ce que tu veux.

J-P

Ce message a été modifié par Jaypee - 26 Oct 2015, 08:12.
Go to the top of the page
 
+Quote Post
toluol
posté 26 Oct 2015, 13:29
Message #5


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Oui... bien-sûr... le style pourrait être mieux écrit... De même que ma classe ne sert pas à grand chose... Mais c'était pour simplifier et expliquer ce que je souhaitais faire...
Cette classe "myClass" n'est qu'un prétexte pour te montrer que j'aimerais utiliser ses méthodes à travers un autre objet (en l'occurrence, créé par l'autre classe jsonObject)

Est-ce complètement impossible ?

Je vais t'expliquer un peu plus mon "vrai" projet alors... Cela t'aidera peut-être à "mieux me suivre" et à m'orienter...
Dans mon programme, j'ai un tableau représentant les lignes d'une table mysql et un bouton "+" pour ajouter de nouvelles entrées.
La ligne du tableau est définie par une méthode afin de choisir ce que je veux très facilement : par exemple, un numéro de position, un id, un nom, un bouton "effacer la ligne".
La méthode de ma class s'occupe de me créer le code html en conséquence (avec le id, par exemple, nécessaire au bouton "effacer la ligne")
La finalité, c'est qu'en cliquant sur le bouton "+", cela ajoute une entrée à la base (en ajax), récupère le dernier id de ma table mysql, et me retourne un code html (celui d'une ligne, créé par ma classe) pour l'ajouter à mon tableau grâce à jquery.

J'espère que je ne t'ai pas perdu en route... ! tongue.gif

C'est pour cela qu'au moment où je clique sur le bouton "+", j'ai fait en sorte que javascript récupère (en json) mon objet php (celui qui définit ma ligne de tableau par divers éléments html) et le retransmet à son tour à un fichier php afin de modifier la base SQL et de me retourner une nouvelle ligne html. Le seul soucis que j'ai en définitive, c'est que, dans ce dernier fichier PHP, je récupère un objet json avec toutes mes infos, mais que je n'arrive plus à utiliser la méthode de ma classe principale "prête à l'emploi" pour récréer une nouvelle ligne...

J'avais réussi à faire tout cela en procédural (j'avais même sollicité votre aide en JS dans un autre post), mais je me disais qu'en POO, ce serait nettement plus robuste et évolutif.
Je suis juste coincé par les méthodes des classes que je ne sais pas réutiliser sur un objet json.

voilà. Mais le principe pourrait être le même avec une simple classe qui calcule 2 petits bidules. Imagine juste que l'objet est récupéré ensuite en javascript grâce à un bouton... puis envoyé en POST à un deuxième fichier php. Mais ce n'est plus le même objet... C'est un objet json. Comment faire ensuite pour continuer à calculer dans le 2e fichier avec les méthodes de ma Classe principale ?

Encore un grand merci pour ta patience ! smile.gif

Ce message a été modifié par toluol - 26 Oct 2015, 13:30.
Go to the top of the page
 
+Quote Post
yponomeute
posté 26 Oct 2015, 13:37
Message #6


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 4 969
Inscrit : 26 Jan 2011
Lieu : Pollachius virens
Membre no 164 083



Je n'ai pas tout lu dans le détail, mais si j'ai bien compris ton problème, tu es en train d'essayer d'utiliser une méthode de la class MyClass avec un objet de la class jsonObject. Il est donc normal que ça fonctionne pas et le message d'erreur est assez explicite :

Citation
Call to undefined method JSONObject::divide()


--------------------
MBP 2017 15" avec clavier pourri et touchbar inutile
Go to the top of the page
 
+Quote Post
toluol
posté 26 Oct 2015, 18:13
Message #7


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Citation (yponomeute @ 26 Oct 2015, 13:37) *
tu es en train d'essayer d'utiliser une méthode de la class MyClass avec un objet de la class jsonObject. Il est donc normal que ça fonctionne pas


Oui, je m'en suis rendu compte, mais comment pourrais-je alors utiliser des données json et utiliser des méthodes d'une classe?
Peut-être que je pourrais créer une méthode qui me modifie toutes les valeurs de mon objet avec les données json ? ...Mais cela me paraît chaud à faire...


Ce message a été modifié par toluol - 26 Oct 2015, 18:27.
Go to the top of the page
 
+Quote Post
No6
posté 26 Oct 2015, 19:57
Message #8


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Ok, j'ai fini par comprendre ton pb...
En fait tu as quelques lacunes sur la programmation objet.

si tu veux ajouter des méthodes à une classe existante (jsonObject) il faut utiliser le mécanisme d'extension de classe.

après, je suis pas trop à l'aise en programmation objet en PHP ( je préfère le c++) mais il me semble comprendre que dans le monde PHP le jsonObject est un type et non une classe et j'ai pas trouvé à quel objet il était lié... ?

Bref quelques liens si ca peut aider ... (?)
http://php.net/manual/fr/reflection.extending.php
http://stackoverflow.com/questions/2599199...m-a-json-object

Ce message a été modifié par No6 - 26 Oct 2015, 23:05.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 26 Oct 2015, 20:12
Message #9


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Citation (No6 @ 26 Oct 2015, 19:57) *
En fait tu as quelques lacunes sur la programation objet.


C'est probable... J'ai commencé il y a quelques jours... ! laugh.gif
Et effectivement, les extensions, je n'avais pas encore compris à quoi cela sert...

Merci pour les liens. Je vais potasser.

Ce message a été modifié par toluol - 26 Oct 2015, 20:25.
Go to the top of the page
 
+Quote Post
No6
posté 26 Oct 2015, 23:21
Message #10


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Désolé, j'ai été plutôt imprécis: par Extends, il s'agit du mécanisme d'héritage.

mais en regardant le bout de code sur stackoverflow il l'utilise sur l'abstraction d'une classe PHP
(sincèrement j'ai pas creusé la question)

donc pour repartir sur de bonnes bases en POO sur PHP je te conseille vivement :
http://www.grafikart.fr/formations/programmation-objet-php
ou si tu pars de plus loin : http://www.grafikart.fr/formations/php-debutant
ces cours sont très bien fait, et les suivre d'un bout à l'autre est loin d'être une perte de temps. cool.gif

et puis après pour les "abstractions" j'ai trouvé ça mais c'est peut être superficiel...
http://www.apprendre-php.com/tutoriels/tut...et-finales.html


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 27 Oct 2015, 00:03
Message #11


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Merci... Oui, les vidéos grafikart sont top ! J'en ai regardé 3, et j'avais pour l'instant compris toute cette base là, mais c'est bien de revoir.
Je continuerai, merci.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 26th April 2024 - 06:44