Les variables PHP sont-elles transmises par valeur ou par référence?

Les variables PHP sont-elles transmises par valeur ou par référence?

0
ajouté édité
Vues: 7
ajouté l'auteur nawfal, source

13 Réponses

PHP variables are assigned by value, passed to functions by value, and when containing/representing objects are passed by reference. You can force variables to pass by reference using an &

Affecté par valeur / exemple de référence:

$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";

print ("var1: $var1, var2: $var2, var3: $var3);

produirait

var1: test, var2: test final, var3: test final

Passé par valeur / référence exampe:

$var1 = "foo";
$var2 = "bar";

changeThem($var1, $var2);

print "var1: $var1, var2: $var2";

function changeThem($var1, &$var2){
    $var1 = "FOO";
    $var2 = "BAR";
}

produirait:

var1: foo, var2 BAR

Variables d'objet passées par l'exemple de référence:

class Foo{
    public $var1;

    function __construct(){
        $this->var1 = "foo";
    }

    public function printFoo(){
        print $this->var1;
    }
}


$foo = new Foo();

changeFoo($foo);

$foo->printFoo();

function changeFoo($foo){
    $foo->var1 = "FOO";
}

produirait:

FOO

(ce dernier exemple pourrait être mieux probablement ...)

0
ajouté
Les "objets" ne sont pas des valeurs en PHP5 et ne peuvent pas être "passés". La valeur de $ foo est un pointeur vers un objet . $ foo est transmis par valeur à la fonction changeFoo() , car changeFoo() n'a pas déclaré son paramètre avec un & .
ajouté l'auteur newacct, source

C'est en fonction de la Documentation PHP .

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition.

<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}

$str = 'This is a string, ';
add_some_extra($str);
echo $str;    // outputs 'This is a string, and something extra.'
?>
0
ajouté
J'ai aussi eu ce doute (débutant) - donc juste pour être clair, ce serait le même que $ str = add_some_extra ($ str); si je n'utilisais pas la référence, non? alors quelle est la vraie valeur ajoutée de cela?
ajouté l'auteur Obmerk Kronen, source
@Obmerk Si vous n'utilisiez pas l'esperluette pour signifier par référence, ce ne serait pas équivalent. Remarquez que la fonction n'a pas d'instruction return, donc $ str sera assigné null, dans votre cas.
ajouté l'auteur Kimberly W, source
Si vous le faites de cette façon @ObmerkKronen alors vous devrez retourner la valeur et l'attraper à travers votre code aussi. La variable initiale restera la même sinon.
ajouté l'auteur Nabeel Khan, source
Je me demande si le passage par renvoi a des avantages sur le plan du rendement ou non? Je passe un grand tableau et par défaut il est passé par valeur. Donc, si j'utilise l'appel par référence alors, y aura-t-il des avantages de performance? (garder les valeurs de tableau inchangées pendant tout le processus)
ajouté l'auteur Choxx, source
le vrai avantage est que vous pouvez manipuler / renvoyer des valeurs multiples. Vous pouvez également passer des variables par référence tout en laissant la fonction retourner quelque chose.
ajouté l'auteur MA-Maddin, source

Les variables contenant des types primitifs sont passées par valeur dans PHP5. Les variables contenant des objets sont transmises par référence. Il y a un article assez intéressant de Linux Journal de 2006 qui mentionne ceci et d'autres différences OO entre 4 et 5.

http://www.linuxjournal.com/article/9170

0
ajouté
Toutes les variables sont passées par valeur dans PHP si le paramètre de la fonction n'a pas de & .
ajouté l'auteur newacct, source

Il semble que beaucoup de gens se perdent dans la façon dont les objets sont transmis aux fonctions et ce qui passe par référence. Les variables d'objets sont toujours passées par valeur, c'est juste la valeur qui est passée en PHP5 est un handle de référence. Comme preuve:

<?php
class Holder {
    private $value;

    public function __construct($value) {
        $this->value = $value;
    }

    public function getValue() {
        return $this->value;
    }
}

function swap($x, $y) {
    $tmp = $x;
    $x = $y;
    $y = $tmp;
}

$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);

echo $a->getValue() . ", " . $b->getValue() . "\n";

Les sorties:

a, b

To passer par référence signifie que nous pouvons modifier les variables qui sont vues par l'appelant. Ce qui clairement le code ci-dessus ne fait pas. Nous devons changer la fonction d'échange pour:

<?php
function swap(&$x, &$y) {
    $tmp = $x;
    $x = $y;
    $y = $tmp;
}

$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);

echo $a->getValue() . ", " . $b->getValue() . "\n";

Les sorties:

b, a

afin de passer par référence.

0
ajouté
Ce n'est pas une preuve . La sortie du premier exemple correspond exactement à ce que l'on attendrait si la valeur actuelle de l'objet entier était transmise à la fonction swap ; en d'autres termes, si les objets étaient "passés en valeur". D'un autre côté, c'est aussi exactement ce à quoi on s'attendrait si un handle d'objet était passé à la fonction, ce qui est en fait ce qui se passe. Votre code ne fait pas la distinction entre ces deux cas.
ajouté l'auteur EML, source
Je pense que cette preuve est une mauvaise interprétation. Il semble que vous essayiez d'échanger des références. Vous avez un problème avec la façon dont les objets sont affectés. Vous réaffectez la référence qui est immuable. C'est la valeur vers laquelle il pointe qui peut être changée de l'intérieur. La redéfinition de swap passe maintenant ** x, ce qui vous permet de changer * x. Le problème est de penser que $ x = $ y changerait ce que $ x indique à l'origine.
ajouté l'auteur grantwparks, source

Dépend de la version, 4 est par valeur, 5 est par référence.

0
ajouté
Je ne pense pas que ce soit vrai.
ajouté l'auteur Nick Heiner, source

http://www.php.net/manual/fr/migration5.oop.php

En PHP 5, il y a un nouveau modèle d'objet. La gestion des objets par PHP a été complètement réécrite, permettant de meilleures performances et plus de fonctionnalités. Dans les versions précédentes de PHP, les objets étaient gérés comme des types primitifs (par exemple des entiers et des chaînes). L'inconvénient de cette méthode était que sémantiquement, l'objet entier était copié lorsqu'une variable était affectée, ou transmis en tant que paramètre à une méthode. Dans la nouvelle approche, les objets sont référencés par handle, et non par value (on peut considérer un handle comme l'identifiant d'un objet).

0
ajouté

En PHP, les objets par défaut sont passés en tant que copie de référence à un nouvel objet.

Voir cet exemple .............

class X {
  var $abc = 10; 
}

class Y {

  var $abc = 20; 
  function changeValue($obj)
  {
   $obj->abc = 30;
  }
}

$x = new X();
$y = new Y();

echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 30

Maintenant, voyez ça ..............

class X {
  var $abc = 10; 
}

class Y {

  var $abc = 20; 
  function changeValue($obj)
  {
    $obj = new Y();
  }
}

$x = new X();
$y = new Y();

echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 10 not 20 same as java does.

Maintenant, voyez ça ..............

class X {
  var $abc = 10; 
}

class Y {

  var $abc = 20; 
  function changeValue(&$obj)
  {
    $obj = new Y();
  }
}

$x = new X();
$y = new Y();

echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 20 not possible in java.

J'espère que vous pouvez comprendre cela.

0
ajouté
1er ex, la valeur de la référence de l'obj est passée à la fonction, les changements à l'obj utilisant la nouvelle référence refléteront à toutes les autres références pointant vers la même obj. 2ème ex, encore une fois la VALEUR de la référence de l'obj est passée à la fonction, la fonction change la valeur de la référence pour pointer vers un nouvel obj, l'ancien obj reste le même. 3ème ex, la référence de la valeur de la référence de l'obj est passée dans la fonction, ainsi les changements dans la fonction opèrent sur le même obj.
ajouté l'auteur s-hunter, source
Cela illustre très bien comment fonctionne l'objet PHP.
ajouté l'auteur Frederik Krautwald, source

Vous pouvez passer une variable à une fonction par référence. Cette fonction sera capable de modifier la variable d'origine.

Vous pouvez définir le passage par référence dans la définition de la fonction:

<?php
function changeValue(&$var)
{
    $var++;
}

$result=5;
changeValue($result);

echo $result; // $result is 6 here
?>
0
ajouté

Utilisez ceci pour les fonctions lorsque vous souhaitez simplement modifier la variable d'origine et la renvoyer au même nom de variable avec sa nouvelle valeur assignée.

function add(&$var){ // The & is before the argument $var
   $var++;
}
$a = 1;
$b = 10;
add($a);
echo "a is $a,";
add($b);
echo " a is $a, and b is $b"; // Note: $a and $b are NOT referenced
0
ajouté

Vous pouvez le faire de toute façon.

put a '&' symbol in front and the variable you are passing becomes one and the same as its origin. ie: you can pass by reference, rather than making a copy of it.

alors

    $fred = 5;
    $larry = & $fred;
    $larry = 8;
    echo $fred;//this will output 8, as larry and fred are now the same reference.
0
ajouté
Ceci est obsolète et génère un avertissement
ajouté l'auteur fijiaaron, source

Les objets sont passés par référence dans PHP 5 et par valeur dans PHP 4. Les variables sont passées par valeur par défaut!

Read here: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html

0
ajouté
Les "objets" ne sont pas des valeurs en PHP5 et ne peuvent pas être "passés". Toutes les variables sont passées par valeur si le paramètre de la fonction transmise n'a pas & .
ajouté l'auteur newacct, source
@ FélixGagnon-Grenier: Encore une fois, les «objets» ne sont pas des valeurs et ne peuvent être «passés». Vous ne pouvez pas avoir une "variable" dans PHP5 dont la valeur est un "objet", vous ne pouvez avoir qu'une valeur qui est une référence d'objet (c'est-à-dire un pointeur sur un objet). Bien sûr, vous pouvez passer ou affecter un pointeur à un objet par valeur et modifier l'objet vers lequel il pointe en appelant une méthode qui effectue une telle modification. Cela n'a rien à voir avec le passage par référence. Quel type est une valeur et si un paramètre est valeur-passe / passe-par-réfé
ajouté l'auteur newacct, source
@newacct pas tout à fait? Les objets sont quelque peu transmis par référence . Je pense avoir observé que les objets PHP peuvent être modifiés par des fonctions même s'ils ne sont pas définis avec & devant les paramètres de la définition - s'ils ont été passés en valeur l'objet contenu dans la portée qui a appelé la fonction avec lui en tant que paramètre ne serait pas affectée.
ajouté l'auteur Félix Gagnon-Grenier, source
class Holder
{
    private $value;

    public function __construct( $value )
    {
        $this->value = $value;
    }

    public function getValue()
    {
        return $this->value;
    }

    public function setValue( $value )
    {
        return $this->value = $value;
    }
}

class Swap
{       
    public function SwapObjects( Holder $x, Holder $y )
    {
        $tmp = $x;

        $x = $y;

        $y = $tmp;
    }

    public function SwapValues( Holder $x, Holder $y )
    {
        $tmp = $x->getValue();

        $x->setValue($y->getValue());

        $y->setValue($tmp);
    }
}


$a1 = new Holder('a');

$b1 = new Holder('b');



$a2 = new Holder('a');

$b2 = new Holder('b');


Swap::SwapValues($a1, $b1);

Swap::SwapObjects($a2, $b2);



echo 'SwapValues: ' . $a2->getValue() . ", " . $b2->getValue() . "
"; echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "
";

Les attributs sont toujours modifiables lorsqu'ils ne sont pas transmis par référence alors méfiez-vous.

Sortie:

SwapObjects: b, a SwapValues: a, b

0
ajouté

En fait, les deux méthodes sont valides, mais cela dépend de vos besoins. Les valeurs de passe par référence rend souvent votre script lent. Il est donc préférable de passer les variables par valeur en considérant le temps d'exécution. Le flux de code est également plus cohérent lorsque vous transmettez des variables par valeur.

0
ajouté