Passage par référence

Passage par référence - PHP - Programmation

Marsh Posté le 27-03-2007 à 17:58:34    

Hello,  
 
Je voudrais construire une fonction avec un argument passé par référence, mais facultatif.
Autrement dit :
 

Code :
  1. function Manger(&$var = $vardefaut) {
  2. }


 
i.e un mélange de

Code :
  1. function Manger(&$var)


et

Code :
  1. function Manger($var = '')


 
C'est possible ?
 
merci !


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 27-03-2007 à 17:58:34   

Reply

Marsh Posté le 27-03-2007 à 18:01:23    

avec une surcharge de methode peut etre ?

 

enfin c'est avec la POO et les classes ...


Message édité par nemohp le 27-03-2007 à 18:02:31
Reply

Marsh Posté le 27-03-2007 à 20:55:47    

theredled a écrit :


C'est possible ?


 
Oui.
 
edit: indice => ton premier bout de code.

Message cité 1 fois
Message édité par sielfried le 27-03-2007 à 20:56:11

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 28-03-2007 à 00:21:43    

sielfried a écrit :

Oui.
 
edit: indice => ton premier bout de code.


Ca marche chez toi ?


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 28-03-2007 à 05:23:41    

J'ai du mal à cerner l'intéret de la chose?
Parce que si tu attribues une valeur par défaut, c'est que le paramètre est absent dans l'appel, donc tu fais référence à quoi???

Reply

Marsh Posté le 28-03-2007 à 08:30:21    

theredled a écrit :

Ca marche chez toi ?


 

Code :
  1. function foo(&$var = 38) {
  2.  echo '$var avant : ', $var, '<br />';
  3.  $var = 59;
  4.  echo '$var après : ', $var, '<br />';
  5. }
  6.  
  7. echo 'avec valeur par défaut :<br />';
  8. foo();
  9. echo 'avec valeur passée en arg :<br />';
  10. $var = 1;
  11. foo($var);


 
=>
 

Citation :


avec valeur par défaut :
$var avant : 38
$var après : 59
avec valeur passée en arg :
$var avant : 1
$var après : 59


 
Ceci dit, je suis aussi un brin sceptique sur l'intérêt du truc.


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 28-03-2007 à 10:21:31    

sielfried a écrit :

Code :
  1. function foo(&$var = 38) {
  2.  echo '$var avant : ', $var, '<br />';
  3.  $var = 59;
  4.  echo '$var après : ', $var, '<br />';
  5. }
  6.  
  7. echo 'avec valeur par défaut :<br />';
  8. foo();
  9. echo 'avec valeur passée en arg :<br />';
  10. $var = 1;
  11. foo($var);


 
=>
 

Citation :


avec valeur par défaut :
$var avant : 38
$var après : 59
avec valeur passée en arg :
$var avant : 1
$var après : 59



En php 4.4.4 :

Parse error: parse error, unexpected '=', expecting ')'


:/

leflos5 a écrit :

J'ai du mal à cerner l'intéret de la chose?
Parce que si tu attribues une valeur par défaut, c'est que le paramètre est absent dans l'appel, donc tu fais référence à quoi???


En fait j'ai une fonction déja crée et utilisée sur de nombreuses pages/scripts de mon site, seulement à un endroit j'ai besoin qu'elle me retourne deux valeurs au lieu d'une.
Intérêt = gain de temps de prog quoi.


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 28-03-2007 à 10:32:43    

theredled a écrit :

En php 4.4.4 :

Parse error: parse error, unexpected '=', expecting ')'


:/
 
En fait j'ai une fonction déja crée et utilisée sur de nombreuses pages/scripts de mon site, seulement à un endroit j'ai besoin qu'elle me retourne deux valeurs au lieu d'une.
Intérêt = gain de temps de prog quoi.


 
 :??:  tu dis qu'il faut qu'elle te retourne 2 valeurs.... auquel cas ce n'est pas en entrée mais en sortie qu'il faut regarder...
 
et puis pourquoi travailler directement sur la variable plutôt que sur une copie (le & ) ?
Enfin, passe à PHP5, il gére (bien mieux) la POO, et gére aussi mieux les passage par référence (ainsi que la surcharge de méthode)

Reply

Marsh Posté le 28-03-2007 à 11:07:31    

chani_t a écrit :

:??:  tu dis qu'il faut qu'elle te retourne 2 valeurs.... auquel cas ce n'est pas en entrée mais en sortie qu'il faut regarder...
 
et puis pourquoi travailler directement sur la variable plutôt que sur une copie (le & ) ?


Une variable passée en référence fait justement office de sortie, c'est presque son but, non [:petrus dei]

chani_t a écrit :

Enfin, passe à PHP5, il gére (bien mieux) la POO, et gére aussi mieux les passage par référence (ainsi que la surcharge de méthode)


Ah ça faut demander à mon hébergeur :D Mais ça va venir.
 


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 28-03-2007 à 11:21:06    

theredled a écrit :

En php 4.4.4 :

Parse error: parse error, unexpected '=', expecting ')'


:/

 

En fait j'ai une fonction déja crée et utilisée sur de nombreuses pages/scripts de mon site, seulement à un endroit j'ai besoin qu'elle me retourne deux valeurs au lieu d'une.
Intérêt = gain de temps de prog quoi.


plus propre

Code :
  1. list($retour1,$retour2) = mafonction($parametres..) ;
  2. function mafonction($parametres)
  3. {
  4.    blmablablba
  5.    return array($retour1,$retour2);
  6. }
 

mais sinon, faut m'expliquer ce que l'adresse d'un truc déclaré en local  hors de son contexte

 

( en C , ca s'appelle une segmentation fault )

Message cité 1 fois
Message édité par flo850 le 28-03-2007 à 11:22:23
Reply

Marsh Posté le 28-03-2007 à 11:21:06   

Reply

Marsh Posté le 28-03-2007 à 11:23:27    

theredled a écrit :

Une variable passée en référence fait justement office de sortie, c'est presque son but, non [:petrus dei]
...


 
 :D ou est ce que tu as vu jouer ça :D...
 
ça ne fais office de sortie QUE si tu claque le & devant, et encore c'est implicite, car tu viens directement modifier la variable en mémoire et non pas une copie... bref c'est une pratique que je n'aime pas du tout.
 
tu claque un return c'est plus propre à mon sens, et la tu peux retourner autant de variable que tu veux (sous forme d'un tableau hein ;) ) ou alors tu utilise la POO, auquel cas tu travail dans une classe, tu y définis des objets, et tu viens modifier les dits objets avec ta fonction... (ça c'est encore plus propre)
 
EDIT : En partie burned by flo850  [:anack]

Message cité 1 fois
Message édité par chani_t le 28-03-2007 à 11:24:55
Reply

Marsh Posté le 28-03-2007 à 12:54:20    

chani_t a écrit :

:D ou est ce que tu as vu jouer ça :D...

 

ça ne fais office de sortie QUE si tu claque le & devant, et encore c'est implicite, car tu viens directement modifier la variable en mémoire et non pas une copie... bref c'est une pratique que je n'aime pas du tout.

Oui, autrement dit, si la variable passée par référence est passée par référence [:petrus75]

 

Et c'est une pratique que tu n'aimes pas mais c'est comme ça que marchent beaucoup de fonctions PHP et C natives, je vois pas où est le problème...

 
flo850 a écrit :

plus propre

Code :
  1. list($retour1,$retour2) = mafonction($parametres..) ;
  2. function mafonction($parametres)
  3. {
  4.    blmablablba
  5.    return array($retour1,$retour2);
  6. }
 

mais sinon, faut m'expliquer ce que l'adresse d'un truc déclaré en local  hors de son contexte

 

( en C , ca s'appelle une segmentation fault )


C'est une solution, mais justement pour mon problème j'aimerais éviter de tout réécrire chaque appel à la fonction et avec ta solution j'y suis obligé [:airforceone]

 

Pour ta dernière phrase je ne vois pas ce que tu veux dire, "hors de son contexte" ? à aucun moment je ne change de contexte...

Message cité 2 fois
Message édité par theredled le 28-03-2007 à 12:57:22

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 28-03-2007 à 13:31:07    

theredled a écrit :

Oui, autrement dit, si la variable passée par référence est passée par référence [:petrus75]
 
Et c'est une pratique que tu n'aimes pas mais c'est comme ça que marchent beaucoup de fonctions PHP et C natives, je vois pas où est le problème...
...


 
Ba moi ce que j'en dit hein... c'est pas parce que c'est possible et tutilisé que c'est forcément bien/lisible
 
Bref, sinon tu passe par référence une variable bidon que tu auras crée spécialement pour ça.. nan ?
 
style

Code :
  1. 1.
  2. $varp=valeur utile;
  3. $varp2=0;
  4. Manger($varp, $varp2);
  5.       function Manger(&$var, &$var2) {blablablablabalba
  6.       }

Reply

Marsh Posté le 28-03-2007 à 13:33:46    

theredled a écrit :


 
C'est une solution, mais justement pour mon problème j'aimerais éviter de tout réécrire chaque appel à la fonction et avec ta solution j'y suis obligé [:airforceone]
 
Pour ta dernière phrase je ne vois pas ce que tu veux dire, "hors de son contexte" ? à aucun moment je ne change de contexte...


dans le cas suivant :  
function mafonction($var ="prout" )  
 
$var n'existe que dans le contexte de la fonction , pas avant, pas apres
 
si tu veux la passer par adresse, je presume que c'ets pour la reutiliser ensuite.
 
la solution serai de la declarer en debut de script , ou en variable gloable , mais c'est pas top

Reply

Marsh Posté le 28-03-2007 à 14:18:52    

chani_t a écrit :

Ba moi ce que j'en dit hein... c'est pas parce que c'est possible et tutilisé que c'est forcément bien/lisible

 

Bref, sinon tu passe par référence une variable bidon que tu auras crée spécialement pour ça.. nan ?

 

style

Code :
  1. 1.
  2. $varp=valeur utile;
  3. $varp2=0;
  4. Manger($varp, $varp2);
  5.       function Manger(&$var, &$var2) {blablablablabalba
  6.       }



Vala, ou plutot genre:

Code :
  1. function GetValeurs(&$var, &$var2) {
  2.   $var = $var2 = 0;
  3.   // blabla
  4.   return $touvabien ? true : false;
  5. }
  6. //$varp et $varp2 n'exitsent pas avant.
  7. if (GetValeurs($varp, $varp2)) echo 'chouette';
 
flo850 a écrit :

dans le cas suivant :
function mafonction($var ="prout" )

 

$var n'existe que dans le contexte de la fonction , pas avant, pas apres

 

si tu veux la passer par adresse, je presume que c'ets pour la reutiliser ensuite.

 

la solution serai de la declarer en debut de script , ou en variable gloable , mais c'est pas top

 

En fait voila la vraie fonction :

function AddTaxes($montant) {
 global $prix_limite, $taxes;
 if ($montant and $montant<=$prix_limite) return ($montant+$taxes);
 else return $montant;
}


La fonction retourne $montant ajouté des $taxes éventuelles.

 

Seulement à un seul endroit de mon site je voudrais savoir en plus si oui ou non, des taxes ont été ajoutées.
Aux autres endroits, je m'en fout.

 

Donc je voudrais pouvoir retourner un booleen ( function AddTaxes($montant, &$taxesOuPas) {}, appelée par $prixapres = AddTaxes($prix, $taxesoupas); )
Mais aux endroit où ça ne m'intéresse pas, je n'ai pas besoin de lui (fonctions appelée par $prixapres = AddTaxes($prix)). Dans ces cas &$taxesOuPas serait justement une variable déclarée en local dans la fonction et inutilisable ailleurs, ça toimbe bien, j'en ai pas besoin.

 

Maintenant je peux simplement comparer $prix et $prixapres pour savoir si des taxes ont été ajoutées, mais bon.


Message édité par theredled le 28-03-2007 à 14:21:57

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 28-03-2007 à 14:31:39    

et si tu faisait comme suit

Code :
  1. function AddTaxes($montant, $taxe=false) {
  2. global $prix_limite, $taxes;
  3. if ($montant and $montant<=$prix_limite) {
  4. if (!taxe) {
  5. return ($montant+$taxes); }
  6. else {
  7. $tab[0]=$montant+$taxes;
  8. $tab[1]=$taxes;
  9. return ($tab);
  10. }
  11. else return $montant;
  12. }


 
mais bon c'est un peu bancal et bricolage... c'est dommage que ce ne soit pas implémenté dans une classe... ça aurait été plus propre m'enfin

Reply

Marsh Posté le 28-03-2007 à 15:18:17    

chani_t a écrit :

et si tu faisait comme suit

Code :
  1. function AddTaxes($montant, $taxe=false) {
  2. global $prix_limite, $taxes;
  3. if ($montant and $montant<=$prix_limite) {
  4. if (!taxe) {
  5. return ($montant+$taxes); }
  6. else {
  7. $tab[0]=$montant+$taxes;
  8. $tab[1]=$taxes;
  9. return ($tab);
  10. }
  11. else return $montant;
  12. }


 
mais bon c'est un peu bancal et bricolage... c'est dommage que ce ne soit pas implémenté dans une classe... ça aurait été plus propre m'enfin


Bien vu, pourquoi pas [:canaille]
Mais $taxesOuPas = ($prixavant != $prixapres); marche bien aussi :D


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 28-03-2007 à 15:33:40    

ba vi, en effet .... [Mode chieur ON] Mais alors pourquoi tu nous embéte avec c'te question :D
Pis d'abord, j'aime pas les écritures abrégées :p ;)[Mode OFF]

Reply

Marsh Posté le 28-03-2007 à 15:36:42    

chani_t a écrit :


et puis pourquoi travailler directement sur la variable plutôt que sur une copie (le & ) ?


En PHP4, la copie n'est-elle pas le comportement par défaut ? Me semblait qu'il fallait le & pour un passage par référence sous PHP4.

Reply

Marsh Posté le 28-03-2007 à 15:46:07    

Djebel1 a écrit :

En PHP4, la copie n'est-elle pas le comportement par défaut ? Me semblait qu'il fallait le & pour un passage par référence sous PHP4.


yep, mais c'est toujours le cas sous PHP5... si tu ne précise pas il utilise une copie ;)
Tu peux le préciser à deux endroits, soit dans la fonction, soit dans l'appel il me semble

Reply

Marsh Posté le 28-03-2007 à 18:14:26    

euuuuuuh, non ^^

Citation :

C'est une différence fondamentale entre la version 4 et la version 5 de PHP : PHP4 passe les objets par copie par défaut, et par référence avec l'opérateur &, tandis que PHP5 les passe par référence implicitement.


lien trouvé vite fait sur google : http://developpeur.journaldunet.co [...] t-1b.shtml
 
A moins que ça ne s'applique qu'aux objets, mais j'en serais bien étonné.

Reply

Marsh Posté le 29-03-2007 à 00:14:52    

Djebel1 a écrit :

euuuuuuh, non ^^
 
lien trouvé vite fait sur google : http://developpeur.journaldunet.co [...] t-1b.shtml
 
A moins que ça ne s'applique qu'aux objets, mais j'en serais bien étonné.


Euh, j'espère que ça ne s'applique qu'aux objets, sinon tout mon site est à refaire pour le changement de serveur [:mr blue]


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 29-03-2007 à 00:51:39    

C'est ça de s'amuser à utiliser un truc qu'est même pas correctement défini dans la doc officielle... :ange: Surtout si c'est fait en PHP 4
 
Teste et "debugge" avant de refaire, ça devrait suffire comme ça.

Reply

Marsh Posté le 29-03-2007 à 03:19:04    

Donc j'avais raison:
1) je vois pas l'intéret (comme dit c'est pas le but du passage par référence)
2) c'est crade parce que devoir gérer des variables "réservées" c'est de l'utopie puis du travail de gros goret :D
 
Si t'as besoin de plusieurs variables en sortie t'as le tableau comme on t'a déjà dit, sinon faut te poser la question de l'utilité pour une fonction de retourner plusieurs variables :spamafote:

Reply

Marsh Posté le 29-03-2007 à 09:48:29    

Notez aussi une chose, quand on parle "par copie", c'est pas vraiment par copie. Faut pas s'amuser à tout passer par référence pour des histoires de conso mémoire ou de perfs, à la base y'a pas de notion de copie.
 
Pour faire les tests suivants, choppez xDebug
 
Prenez une variable simple, et regardez la zval correspondante :

Code :
  1. $a = 5;
  2. echo xdebug_debug_zval('a');


Résultat :

Code :
  1. a:
  2. (refcount=1, is_ref=0),int 5


 
Maintenant on va déclarer une autre variable égale à celle-là, sans référence :

Code :
  1. $b = $a;
  2. echo xdebug_debug_zval('a');
  3. echo xdebug_debug_zval('b');


Résultat :

Code :
  1. a:
  2. (refcount=2, is_ref=0),int 5
  3. b:
  4. (refcount=2, is_ref=0),int 5


Là on voit que b et a pointent sur la même zval (refcount est passé à 2) : ce n'est pas une copie, c'est la même zval. Notez que le champ is_ref est à 0, on n'a pas fait de référence.
 
Si maintenant on déclare par référence :

Code :
  1. $c =& $a;
  2. echo xdebug_debug_zval('a');
  3. echo xdebug_debug_zval('b');
  4. echo xdebug_debug_zval('c');


 
Résultat :

Code :
  1. a:
  2. (refcount=2, is_ref=1),int 5
  3. b:
  4. (refcount=1, is_ref=0),int 5
  5. c:
  6. (refcount=2, is_ref=1),int 5


 
Là, boom : a et c pointent sur la même zval, et is_ref est passé à 1. Mais regardez b... Lui a du coup sa propre zval à lui, c'est seulement à ce moment là que la copie à été réalisée.
 
C'est un peu la même chose lors d'une réassignation :

Code :
  1. $a = 5;
  2. $b = $a;
  3. $b = 6;


Lors du $b = $a, $b pointe sur la même zval que $a. C'est uniquement lorsqu'on modifie $b qu'une nouvelle zval est crée.
 
 
Maintenant avec des classes objets, en PHP5, y'a plus de copie, il faut obligatoirement implémenter la méthode magique __clone pour pouvoir retourner une copie...
 

Reply

Marsh Posté le 29-03-2007 à 10:19:01    

lkolrn a écrit :

C'est ça de s'amuser à utiliser un truc qu'est même pas correctement défini dans la doc officielle... :ange: Surtout si c'est fait en PHP 4
 
Teste et "debugge" avant de refaire, ça devrait suffire comme ça.


En attendant ce serait très très surprenant, ce serait bien le premier language qui passe par défaut les variables par référence nan ?

leflos5 a écrit :

Donc j'avais raison:
1) je vois pas l'intéret (comme dit c'est pas le but du passage par référence)
2) c'est crade parce que devoir gérer des variables "réservées" c'est de l'utopie puis du travail de gros goret :D
 
Si t'as besoin de plusieurs variables en sortie t'as le tableau comme on t'a déjà dit, sinon faut te poser la question de l'utilité pour une fonction de retourner plusieurs variables :spamafote:


1) Quel est selon toi le but du passage par référence alors ?
2) Rien compris :D


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 29-03-2007 à 10:57:30    

J'ai la flemme de faire le test si qqn a le courage, mais en fait je me dis que ça doit s'appliquer qu'aux objets le passage par référence, par défaut. Pour les variables, ça pourrait foutre un beau bordel.
 

theredled a écrit :

Euh, j'espère que ça ne s'applique qu'aux objets, sinon tout mon site est à refaire pour le changement de serveur [:mr blue]


Bah non. Si tu as fais du passage par référence en utilisant &, ça ne changera rien en tournant sous PHP5. Le seul truc qui serait chiant, c'est si tu as fait du passage par copie et qu'ensuite tu modifiais allègrement la variable dans ta fonction. Mais comme dit plus haut, je ne pense pas que ça s'applique aux variables à la réflexion.
 

theredled a écrit :

En attendant ce serait très très surprenant, ce serait bien le premier language qui passe par défaut les variables par référence nan ?


Mouais, ça doit s'appliquer qu'aux objets.

Reply

Marsh Posté le 29-03-2007 à 11:07:03    

doc PHP5 ...  
Depuis PHP 5, new retourne une référence automatiquement, donc, l'utilisation de =&  dans ce contexte est obsolète et produit un message de degré E_STRICT.
 
et puis :
Dans les versions récentes de PHP, vous devriez recevoir une alerte disant que "Call-time pass-by-reference" est obsolète lorsque vous utilisez un & dans foo(&$a);.
 
Moralité, le passage par référence n'est automatique QUE pour les objets (utilisation de new)... :D

Reply

Marsh Posté le 29-03-2007 à 11:14:08    

Oui, c'est que pour les objets. Et on peut pas passer par copie un objet, il faut faire un clone dans la fonction par exemple.

Reply

Marsh Posté le 29-03-2007 à 11:24:42    

non mais oui c'était logique, j'étais un peu endormi en postant :'( Quand j'ai lu ton message j'ai pensé objet direct en  oubliant les variables ^^

Reply

Marsh Posté le 29-03-2007 à 11:40:06    

Djebel1 a écrit :

Bah non. Si tu as fais du passage par référence en utilisant &, ça ne changera rien en tournant sous PHP5. Le seul truc qui serait chiant, c'est si tu as fait du passage par copie et qu'ensuite tu modifiais allègrement la variable dans ta fonction. Mais comme dit plus haut, je ne pense pas que ça s'applique aux variables à la réflexion.


Bravo, c'est exactement ce que je disais :D


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed