Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Passage de parametre par reference

4 réponses
Avatar
Christophe MERESSE
Bonsoir,

Après relecture de la doc php sur les conseils des modérateurs, je
reste toujours bloqué devant le problème suivant:

J'aimerais passer une variable par référence a une fonction afin de lui
créer un alias.

function set_a(&$v)
{
global $a;
$a=&$v;
}
$b=1;
$a=1;
set_a($b); // <- ça, ça marche pas
// $a=&$b; // <- ça, ça marche
$b=2;
echo "a: $a.et b: $b";

J'aimerais obtenir "a: 2 et b: 2" et pas "a: 1 et b: 2" puisque $a et $b
seraient
sensés "pointer" sur le même contenu après l'appel de la fonction.

J'ai trouvé dans la doc un utilisateur qui pose une question semblable:
****************************************
joachim at lous org
19-May-2003 02:39
Something is very fishy with object-by-reference semantics:
It doesn't seem to be possible to replace the passed object references with
other references:

class a{
var $val;
function a($val){ $this->val = $val;}
}
function replace(&$src, &$dest){
$dest =& $src;
}
$src = new a(2);
$dest = new a(1);
replace($src,$dest);
$src->val=5;
echo $dest->val;

This code prints "1", not "5".
Changing the '=&' with '=' you gets you '2', as expected.
I can find no way to get the actual reference across.

I can work around it by returning the reference in stead, but that only
works for one ref.
*******************************************

Bref, c'est exactement mon problème en dehors du fait que lui passe sa
variable $dest par référence aussi
alors que moi j'utilise un "global" et une variable dont je connais déjà le
nom.

Qui peut m'expliquer ce mystère... ?
Merci
Christophe

4 réponses

Avatar
Jean-Marc Molina
Bonjour,

global $a;


En fait je crois que global créé une référence, ça n'est pas le $a globale
mais une référence qui est créée pour être utilisée dans la fonction.

$a=&$v;


Ici tu affectes une référence d'une référence ($b -> &$v -> &&$b) à une
référence ($a -> global $a). Si tu affiches $a dans ta fonction, ça
fonctionne, par contre à sa sortie ça ne fonctionne plus.

Ça peut être utile d'essayer tout ça pour un exercice mais j'espère que tu
n'utilises pas ce genre de bidouilles dans tes scripts :). Je trouve ça un
peu tordu :D

Avatar
Christophe MERESSE
global $a;


En fait je crois que global créé une référence, ça n'est pas le $a globale
mais une référence qui est créée pour être utilisée dans la fonction.


Oui effectivement c'est ce que j'ai lu aussi "global $a;" est équivalent à
"$a = &$GLOBALS[a];"


$a=&$v;


Ici tu affectes une référence d'une référence ($b -> &$v -> &&$b) à une
référence ($a -> global $a). Si tu affiches $a dans ta fonction, ça
fonctionne, par contre à sa sortie ça ne fonctionne plus.

Ça peut être utile d'essayer tout ça pour un exercice mais j'espère que tu
n'utilises pas ce genre de bidouilles dans tes scripts :). Je trouve ça un
peu tordu :D


Heu c'est pas exactement ca mais ca s'en approche. J'affecte l'instance
d'une classe à un
parametre d'une autre instance (dans une methode de la classe)...
C'est vrai que ca n'est peut-etre pas courant mais est-ce pour autant
tordu... ? :)
En fait j'ai résolu mon probleme qui venait uniquement du passage par
parametre car je ne
savais pas le faire il y a 3 jours. Et le probleme soulevé ici n'apparait
pas lorsqu'on fait
un $this->a=&$v;

Par contre j'ai un peu fais avancer le shmilblick à force de chercher dans
la doc et
dans les bug de php...

Encore plus fort:

function foo(&$b)
{
global $a;
$a=&$b;
}
$a=1;
$b=1;
foo($b);
$b=2;
echo $a; // Renvoie 1 --> marche pas

Par contre:

function foo(&$b)
{
$GLOBALS[a]=&$b;
}
$a=1;
$b=1;
foo($b);
$b=2;
echo $a; // Renvoie 2 --> ca marche !!

En gros on dirait que bien qu'on mette "global", $a ne l'est pas vraiment...

J'ai vu quelques bug ouverts depuis un certain temps qui semblent toucher
plus ou moins au même problème:
http://bugs.php.net/bug.php?id645
http://bugs.php.net/bug.php?id"847
http://bugs.php.net/bug.php?id419

J'ai l'impression que ca necessiterait un coup d'oeil dans les sources de
php, malheureusement
j'ai peu de temps pour faire ca :)

Voila
Merci pour ta réponse Jean-Marc.
Christophe


Avatar
Jean-Marc Molina
Bonjour Christophe,

Très intéressant tout ça, en effet si tu utilises GLOBALS directement, vu
que ça n'est pas une référence, tu modifies directement $a. Tout ça n'est
pas très logique de toutes façons. Perso je n'utilise jamais global, ça
devrait être interdit ce genre de fonctionnalités. Enfin avec PHP on est
plus à ça près :(.

Pour résumer avec global on peut faire tout et n'importe quoi et avoir des
bogues et des erreurs partout dans son application. Ça empêche tout contrôle
de la part des concepteurs-développeurs d'une application.

Enfin bon ravis de voir que ça fonctionne ! Moi je te conseille de passer
tout ça en paramètre à ta fonction sinon tu ne vas pas t'en sortir.

Bonne journée,
JM
Avatar
cmeresse
Ca y est j'ai compris !!
C'est moi qui interprete mal ces histoires de references.

En fait faire ce que je fais dans ma fonction revient à faire ca:

$a = 1;
$b = 1;
// debut de la fonction
$global_a = &$a;
$global_a = &$b;
// fin de la fonction
$b = 2;
echo $a;

Et quand la doc dit que quand on fait $a=&$b; , $a et $b sont
"completement égales", c'est vrai sauf si on reassigne une nouvelle
reference...

$global_a = &$a;
$global_a = &$b;

n'est pas equivalent à

$global_a = &$a;
$a = &$b;

Ouf !
Désolé pour le remu-menage :)
Et encore merci à Jean-Marc qui m'a fait mieux reflechir.

Christophe