Les références dans une déclaration d?objet ou dans un constructeur. [Résolu]

Signaler
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
Bonjours,


Je me forme actuellement sur le PHP (tout seul comme un
grand, avec un cours trouver sur le net). Il y à néanmoins une nuance que je n’arrive
pas à saisir (ou peut être que je comprends le principe mais c’est la syntaxe que
je ne comprends pas, voire le contraire, bon j’arrêt…) : Les références
dans une déclaration d’objet ou dans un constructeur.
Donc déjà pour résumer ce que je sais (ou crois savoir ;-))



Un constructeur est une fonction qui n’a comme différance avec les autres fonctions de ma classe uniquement le fais qu’elle porte le même nom que la classe (il faux donc faire attention quand on fait des "extends" mais ça je crois avoir compris).









Ma question est (ou plutôt mes questions sont) :





Dans tout les cas je considère que c’est la 1ér exécution de mon script (donc 1ér déclaration de mes variables).





<!--[if !supportLists]-->

1)

<!--[endif]-->
Je défini une classe Toto. Le nom de mon constructeur est donc Toto qui reçoit comme paramètre Valeur (qui est une chaine de caractére et sera stockée dans une variable $Nom par exemple). Je crée mon objet : « $a = &new Toto("Chaine de caract.") ». Qu’es que $a ? Un pointeur sur objet ? Un objet ?





<!--[if !supportLists]-->

2)

Si je fais « $a = new Toto » en réalité combien d’objet ai-je défini ? Un, ou un plus une copie stocker dans $a ? Et si deux objets sont déclarer command es que j’accède à l’objet crée réellement ?





<!--[if !supportLists]-->

3)

<!--[endif]-->
Dans mon constructeur je veux que soit stockée dans un tableau global (disons $Tabl) Valeur (en plus de l’affectation dans une variable). Pour cela je fais (dans mon constructeur) « global $Tabl[] = $this->Nom ». Alors $Tabl contiendra une copie de ma chaine. Donc dans ce cas si je modifie la variable $Nom de mon objet &a mon tableau ne sera pas modifier (et vice versa), et ce quel que soit la façon d’ont je déclare $a (soit « $a = new Toto » soit « $a =&new Toto ». (Surtout dite moi si je me trompe, c’est une des seules choses d’ont je sois vraiment sur, heeeeeee, non en faite ne me le dite pas, car dans ce cas je devrais tout reprendre du début, lol , j’en rie mais ca m’embêterais bien)





<!--[if !supportLists]-->

4)

<!--[endif]-->
Bon admettons maintenant que dans mon constructeur je fais cas : « $Tabl[] = &$this->Nom » alors mon tableau contiens l’adresse de ma variable $Nom de l’objet crée. Que se passe t’il si je déclare mon objet $a de la façon suivant « $a = new Toto("Ca c’est mon nom") » ? Si j’ai bien compris alors la variable $a est une copie de mon objet crée. Donc si je modifie la variable $Nom de l’objet $a alors mon tableau $Tabl ne sera pas modifié. Ce que je ne comprend pas c’est que (si j’ai bien compris mon cours) $Tabl[0] sera toujours valide, ce qui reviendrais à dire que mon objet existe réellement deux fois (si non je ne devrais pas pouvoir lire l’adresse contenu par mon tableau $Tabl ou elle contiendra une valeur aléatoire), et ce pour une seul déclaration !!! Donc si je veux que mes deux objets soit accessible je dois faire cas « $b =&new Toto ;$a = $b ; ». Dans ce cas $a est une copie de l’objet crée et $b est un pointeur sur l’objet crée. Je peux donc modifier $a sans incidence sur $Tabl et si je modifie $b la modification s’effectue également sur $Tabl (et vice versa bien sure). Par contre mon constructeur ne s'executera qu'une fois et $a n'est qu'une copie "brute" de $b. Merci de me reprendre si j’ai fais une erreur dans cette partie.








Bon je pense que j’ai fais le tour de mes question (tout du moins sur les classe/objets).








Merci d’avance

14 réponses

Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Hello,

je te conseille de lire ceci :
http://fr3.php.net/manual/fr/language.oop.newref.php

ça me semble bien expliqué. En espèrant que ce ne soit pas le "tuto" dont tu parles (il s'agit de la doc officielle de php).

On parle ici de PHP4, au passage...pas de PHP5 (les choses s'y compliquent ;-) ).
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
41
Salut,

les structures de données... un pointeur en C tu fais soit une struc chainée, soit un malloc de plein d'éléments (soit les deux...) mais dans tout les cas, les arrays et les objets en php peuvent faire ça...

une pile en php se fait avec un array, unset te permet de supprimer un élément...

In a dream, I saw me, drop dead... U was there, U cried... It was just a dream, if I die, U won't cry, maybe, U'll be happy

Mon site (articles sur la programmation et programmes)
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

En PHP 5 c'est pire?!?!?! HAAaaaaaaaaaa!!!
Ce n'est en effet pas le tuto que j'utilise. Je lit celui-çi et repond (peut être à mes propre questions).
En tout cas merci.
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Non en fait en PHP5, le constructeur renvoie une référence.
Donc l'exemple que je t'ai donné sur la doc n'est plus valable. la méthode getName() renverra toujours la même valeur, dans le cas de $bar1.
Le mieux est de tester par toi-même, ceci dit...

<?php
class toto {
    var $sNom;
    function toto ($sChaine) {
        global $aGlob;
        $aGlob[] = &$this -> sNom;
        $this -> setNom ($sChaine);
    }

    function setNom ($sChaine) {
        $this -> sNom = $sChaine;
    }

    function getNom () {
        return $this -> sNom;
    }
}

$a = new toto ('bla');
echo $a -> getNom ();
echo '
';
echo $aGlob[0];
echo '
';

$a -> setNom ('another one');
echo $a -> getNom ();
echo '
';
echo $aGlob[0];
echo '
';
var_dump ($a);
echo '
';
var_dump ($aGlob);
echo '

';

class toto2 {
    var $sNom;
    function toto2 ($sChaine) {
        global $aGlob2;
        $aGlob2[] = &$this;
        $this -> setNom ($sChaine);
    }

    function setNom ($sChaine) {
        $this -> sNom = $sChaine;
    }

    function getNom () {
        return $this -> sNom;
    }
}

$b = new toto2 ('bla');
echo $b -> getNom ();
echo '
';
echo $aGlob2[0] -> getNom ();
echo '
';

$b -> setNom ('another one');
echo $b -> getNom ();
echo '
';
echo $aGlob2[0] -> getNom ();
echo '
';
var_dump ($b);
echo '
';
var_dump ($aGlob2);
echo '

';
?>
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

Bon, ce n'est pas exactement le même tuto (même si cas y resemble beaucoup) mais il reste un détail qui me perturbe. Dans cette partie :

<?php
class a {

    function a($i) {

        $this->value = $i;

        // Essayez de comprendre on n'a pas besoin de

        // référence ici

        $this->b = new b($this);

    }

    function createRef() {

        $this->c = new b($this); //1


    }

    function echoValue() {

        echo "
","class ",get_class($this),': ',$this->value;

    }

}

class b  {

    function b(&amp;$a) {   //2

        $this->a = &amp;$a; //3  C'est ces lignes (1,2,3) qui me posse problème!

    }

   function echoValue() {

        echo "
","class ",get_class($this),': ',$this->a->value;

        }

}
// Essayez de comprendre pourquoi une copie simple va

// conduire à un résultat indésirable à

// la ligne marquée d'une étoile
$a =&amp;new a(10);
$a->createRef();
$a->echoValue();
$a->b->echoValue();
$a->c->echoValue();
$a->value = 11;
$a->echoValue();
$a->b->echoValue(); // *
$a->c->echoValue();

?>


Je résume ce que je comprend quand je lit ceci :
2 classe "a" et "b"
Quand je crée un objet sur la classe "a" un autre objet est crée. Ce dernier est stoqué dans une variable "$b" apparenant à l'objet de la classe "a" et est basé ce sur la classe "b". Pas claire mais je n'arrive pas à l'exprimer mieu.
Je crée un objet sur la classe "a" et place sont adresse dans le pointeur "$a".Problème : quand je crée mon objet "$b" je passe comme paramètre à mon new la variable $this (soit une valeur?!?!?!) et dans le créateur de "b" j'ai un pointeur??? Que se passe t'il si j'ecrit à la place "$this->b &new($this);" ou même "$this->b new(&$this)" (pour moi c'est la dernierre proposition qui est la bonne or je pense que c'est plutôt celle du tuto mais pas moyen de la comprendre avec exactitude, ca viens de moi?)
Mon problème ne viens peut être pas des déclarations de classes/d'objets mais peut être de la gestion des pointeurs?
Je regarde appré des info sur les pointeur en PHP (je poste ce message avant, je suis formé en C/C++ en tout 1ér lieu et je ne comprand pas trés bien la façon dont-on gere les pointeurs en PHP).

Juste pour verif : Une variable n'est pas forcement typé en PHP (comme en VB quand une variable est déclarer en variant,ou pas déclarer du tout mais cas j'aime pas trop, sauf que je peut défiir un objet dans une de cas variable ce qui n'est pas possible en VB, enfain je crois)

Dans le même espris : si c'est les pointeurs que je n'ais pas bien compris
Je fais cas :
<? PHP
$a = "Je suis une chaine de carac."; //Je déclare une chaine de carac et lui affect une valeur
$b = &$a; //Je déclare un pointeur sur chaine qui pointe sur $a
$b .= " Et même un peut plus."; //Je modifi la chaine situé à l'adrs de $b donc la chaine $a (qui deviens du coup "Je suis une chaine de carac. Et même un peut plus.")
?>

Juste une (autre) question au passage : Command es que je re-défini mon pointeur? Je m'explique grace à cette exemple (qui serais alors à la suite du 1ér bout de code ci dessus):
<? PHP
$b = &$c; //Je fais quois ici? Je modifie l'adrs de mon pointeur $b, ou, je met d'adrs de $c dans $a, ou, je met le contenu de $c dans $a? Moi j'opterais pour je met l'adrs de $c dans $a
?>
Quel que soit ce que fais la dernierre ligne de code commant faire les autre cas proposé? (peut être c'est impossible mais cela ferais pas plaisir)
Existe t'il des equivalence des &(adrs, ça à priori oui) et *(ce qui est à l'adrs) en C/C++ pour les pointeurs en PHP???

Oui je sais je tape des pavé, désol.
Merci
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

Heeeeeeeee, j'avias pas vue ton post. J'espaire que je ne pose pas de question au quel tu aurais déjà répondu!!!
Je le lit de suite.
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

Haaaaaa, je fais que des connerie aujourd'hui!!!
La ligne qui me posse problème (ligne N°1) c'est :
$this->b = new b($this);

Qui est dans le créeateur (soit "
function a($i) {

")

Bon bà encors désol (je n'ai pas vraiment la forme dirait-on)
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

Pour ma dernierre question j'ai peut être trouver le solution (tout du moin une mais il exite peut être mieu???)
Je détri ma variable $b et je la réafecte, soit :
<? PHP
$a = "Je suis une chaine de carac."; //Je déclare une chaine de carac et lui affect une valeur
$b = &$a; //Je déclare un pointeur sur chaine qui pointe sur $a
$c = "Ca c'est nouveau!"; //Déclaration de $c
$b
.= " Et même un peut plus."; //Je modifi la chaine situé à l'adrs de $b
donc la chaine $a (qui deviens du coup "Je suis une chaine de carac. Et
même un peut plus.")
$b = $c; //La je met le valeur de $c dans $a (soit à l'adrs pointé par $b)
var_dump $b; //Donc là $b n'existe plus
$b = &$c; //$b pointe maintenant sur $c
?>

Merci de me dire si (et dans ce cas où) je me trompe ou si c'est OK.

De toute façon merci Malalam du temps que tu m'accorde
(promis je le revaudrais à la communauté)
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Ouais ben la suite sera pour demain lol, j'ai trop de taf là.
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

<!--[if gte vml 1]><v:shapetype
id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
<v:stroke joinstyle="miter"/>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"/>
<v:f eqn="sum @0 1 0"/>
<v:f eqn="sum 0 0 @1"/>
<v:f eqn="prod @2 1 2"/>
<v:f eqn="prod @3 21600 pixelWidth"/>
<v:f eqn="prod @3 21600 pixelHeight"/>
<v:f eqn="sum @0 0 1"/>
<v:f eqn="prod @6 1 2"/>
<v:f eqn="prod @7 21600 pixelWidth"/>
<v:f eqn="sum @8 21600 0"/>
<v:f eqn="prod @7 21600 pixelHeight"/>
<v:f eqn="sum @10 21600 0"/>
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
<o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" alt="" style='width:11.25pt;
height:11.25pt'>
<v:imagedata src="file:///C:\DOCUME~1\VIW\LOCALS~1\Temp\msohtml1\01\clip_image001.gif"
o:href="http://www.phpcs.com/imgs2/smile.gif"/>
</v:shape><![endif]-->
<!--[if !vml]-->Bonjours, bien dormis? Bon en tout cas je crois que j'étais
effectivement fatigué hier.
Bon je commence à comprendre (il faudrais que je passe moin de temps par jours à lire ce tutoriel, ca me fatigue et je ne comprand plus rien à ce que je lit à la fin). Les paramètres peuvent être passée par référence
(comme en C++) donc on à pas à envoiler l'adresse des variables de façon explicite
(mais ça me plais pas car ce n'est pas explicite justement, donc je ne
l'utilise jamais en C++, oui je sais je suis un chieur).


Après cette question je te laisse tranquille.


Excite-t-il des pointeurs explicites en PHP (comme en
C/C++)?



Merci
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Je n'ai encore pas eu le temps, désolé.
Peut-être dans la journée...
Mais pour répondre rapidement à ta dernière question, là : non.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
41
Salut,

En Cpp, les pointeurs te servent surtout à faire des listes chainées, et quand tu utilises les libs toutes faites, tu ne les vois prèsque plus...

En php, t'as les array pour ça, le php est un langage fait pour les gens qui n'ont pas envi de se prendre la tête... les pointeurs, c'est la chose la plus chiante en C/C++

In a dream, I saw me, drop dead... U was there, U cried... It was just a dream, if I die, U won't cry, maybe, U'll be happy

Mon site (articles sur la programmation et programmes)
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

    Bonjours,

    Merci pour ces précisions (pas de pointeur explicite en PHP , c'est pas chiant les pointeurs, c'est vachement bien, même si c'est vrais que je m'embrouillais un peut avec au départ, quand tu sais ce que tu fais avec, tu économise pas mal de mémoire, les listes chainées moi j'en fais tout le temps, et j'ai déjà râlé quand je me suis mit au VB je vais peut être pas recommencer, mais bon... en même temps c'est vrais que le PHP s'exécute sur serveur donc la mémoire faux pas en abuser mais logiquement il y à de quoi faire)

    Finalement je crois que j'ai mes réponses. Simplement je ne comprend pas coucou747, les 'array' sont fais pour construire des tableaux dynamiques (à moins que je me trompe, je suis débutant en PHP) pas des listes chainées Si je veut enlever ou ajouter un maillon dans ma chaine je fais command avec 'array' (autrement que de décaler toute les valeurs depuis l'index ou je veut insérer mon maillon jusqu'à la fin du tableau, ou alors cas me parais un peut lourd, mais bon si il n'y a pas d'autre solution)

    Si non Merci bien pour ces réponses
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019

Hé, mais c'est vrais que je peut stoquer une référance dans une structure (référance vers une autre structure egalement, enfin je pense)
Donc effectivement je vois ce que tu veut dire pour la liste chainée.

Ma question été un peut béte.

Plus de question... Pour le momand en tout cas.

Merci encors pour le temps que vous m'avez consacré.