web-dev-qa-db-fra.com

Comment passez-vous les objets par référence dans PHP 5?

Dans PHP 5, devez-vous utiliser le modificateur & pour passer par référence? Par exemple,

class People() { }
$p = new People();
function one($a) { $a = null; }
function two(&$a) { $a = null; )

En PHP4, vous aviez besoin du modificateur & pour conserver la référence après une modification, mais je suis confus sur les sujets que j'ai lus au sujet de l'utilisation automatique de la référence automatique par PHP5, sauf lors du clonage explicite de l'objet.

En PHP5, le modificateur & est-il requis pour passer par référence à tous les types d'objets (variables, classes, tableaux, ...)?

22
Brian Graham

êtes-vous obligé d'utiliser le modificateur & pour passer par référence?

Techniquement/sémantiquement, la réponse est oui , même avec des objets. En effet, il existe deux manières de passer/assigner un objet: par référence ou par identifiant . Quand une déclaration de fonction contient un &, comme dans:

function func(&$obj) {}

L'argument sera passé par référence, quoi qu'il arrive. Si vous déclarez sans le &

function func($obj) {}

Tout sera passé par valeur, à l'exception des objets et des ressources, qui seront ensuite passés via identifier . Qu'est-ce qu'un identifiant? Eh bien, vous pouvez y voir une référence à une référence. Prenons l'exemple suivant:

class A
{
    public $v = 1;
}

function change($obj)
{
    $obj->v = 2;
}

function makezero($obj)
{
    $obj = 0;
}

$a = new A();

change($a);

var_dump($a); 

/* 
output:

object(A)#1 (1) {
  ["v"]=>
  int(2)
}

*/

makezero($a);

var_dump($a);

/* 
output (same as before):

object(A)#1 (1) {
  ["v"]=>
  int(2)
}

*/

Alors, pourquoi $a ne devient-il pas soudainement un entier après l'avoir passé à makezero? C'est parce que nous avons seulement écrasé le identifiant . Si nous avions passé par reference :

function makezero(&$obj)
{
    $obj = 0;
}

makezero($a);

var_dump($a);

/* 
output:

int(0) 

*/

Maintenant, $a est un entier. Donc, il y a une différence entre passer par identifier et passer par référence .

80
webbiedave

Vous l'utilisez mal. Le signe $ est obligatoire pour toute variable. Ce devrait être: http://php.net/manual/fr/language.references.pass.php

function foo(&$a)
{
$a=null;
}


foo($a);
To return a reference, use

 function &bar($a){
$a=5;
return $a

 }

Dans les objets et les tableaux, une référence à l'objet est copiée en tant que paramètre formel. Toute opération d'égalité sur deux objets constitue un échange de référence.

$a=new People();
$b=$a;//equivalent to &$b=&$a roughly. That is the address of $b is the same as that of $a 

function goo($obj){
//$obj=$e(below) which essentially passes a reference of $e to $obj. For a basic datatype such as string, integer, bool, this would copy the value, but since equality between objects is anyways by references, this results in $obj as a reference to $e
}
$e=new People();
goo($e);
0
Somesh Mukherjee

Les objets passeront par référence. Les types intégrés seront passés par valeur (copiés);

Ce qui se passe en coulisse, c'est que lorsque vous transmettez une variable qui contient un objet, c'est une référence à l'objet. Donc, la variable elle-même est copiée, mais elle fait toujours référence au même objet. Donc, il y a essentiellement deux variables, mais les deux pointent vers le même objet. Les modifications apportées aux objets à l'intérieur d'une fonction vont persister.

Dans le cas du code que vous avez là (d'abord vous avez besoin de $ même avec &):

$original = new Object();

one($original); //$original unaffected
two($original); //$original will now be null

function one($a) { $a = null; } //This one has no impact on your original variable, it will still point to the object

function two(&$a) { $a = null; ) //This one will set your original variable to null, you'll lose the reference to the object.
0
Chris