Atribuição por referência
Referências no PHP permitem criar duas
variáveis que se referem ao mesmo conteúdo. Ou seja, quando você faz:
então aqui
$a e
$b
apontam para o mesmo conteúdo.
Nota:
$a e $b são completamente
iguais aqui, mas não porque $a está apontando para
$b ou vice versa, mas sim que
$a e $b apontam para o
mesmo lugar.
Nota:
Se você atribuir, passar ou retornar uma variável indefinida por referência,
ela irá ser criada.
Exemplo #1 Usando referência com variáveis indefinidas
<?php
function foo(&$var) { }
foo($a); // $a é "criada" e setada par null
$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)
$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>
A mesma sintaxe pode ser utilizada com funções, que retornem referências,
e com o operador new
(a partir do
PHP 4.0.4 e antes do PHP 5.0.0):
Desde o PHP 5,
new
retorna referência automaticamente, então
usar
=&
neste contexto é obsoleto e
produz um alerta
E_DEPRECATED
no PHP 5.3 e
posteriores, e um alerta
E_STRICT
nas versões anteiores.
A partir do PHP 7.0 essa é uma construção sintaticamente inválida
(ou tecnicamente, a diferença é que no PHP 5 as variáveis de objeto, assim como
recursos, eram ponteiros simples para os dados do objeto, de forma que essas
referências não eram "referências" no sentido anterior (mais como apelidos).
Para mais informações veja
objetos
e referências.)
Aviso
Se você atribuir uma referência para uma variável declarada global
dentro da função, a referência irá ser visível somente dentro da função.
Você pode evitar isto usando o array $GLOBALS.
Exemplo #2 Referenciando variáveis globais de dentro de funções
<?php
$var1 = "Example variable";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // visível somente dentro da função
} else {
$GLOBALS["var2"] =& $var1; // visível também no contexto global
}
}
global_references(false);
echo "var2 is set to '$var2'\n"; // var2 is set to ''
global_references(true);
echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable'
?>
Veja
global $var;
como atalho para
$var
=& $GLOBALS['var'];
. Assim atribuir outra referência
para
$var
somente modifica a variável de referência local.
Nota:
Se você atribuir um valor para uma variável com referência numa instrução
foreach a referência também é modificada.
Exemplo #3 Referências e o comando foreach
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// faz alguma coisa
}
echo $ref; // 3 - último elemento do array iterado
?>
Ainda que não seja uma atribuição por referência explícita, expressões criadas
com o constructo
array()
também podem
se comportar como tais com o prefixo &
no elemento de array
a ser acrescentado. Exemplo:
Note que referências dentro de arrays são potencialmente perigosas.
Fazer uma atribuição normal (sem referência) com uma referência à
direita não transforma a expressão a esquerda numa referência, mas referências
dentro de arrays são preservadas nessas atribuições normais. Isso também se
aplica a chamadas de função onde arrays são passados por valor. Exemplo:
Em outras palavras, o comportamento de referências em arrays é definido
elemento por elemento. O comportamento de referências dos elementos individualmente
são dissociados da referência do container array.
Passagem por referência
A segunda coisa que referências fazem é passar variáveis por
referência. Isso é feito com a criação de uma variável local em uma função
e uma variável no escopo chamador que referênciem o mesmo
conteúdo. Assim:
a variável
$a será 6 no final. Isto ocorre porque
na função
foo a variável
$var se referem ao mesmo conteúdo de
$a. Para mais informações disso veja
a seção de
passagem por
referência.