As variáveis PHP são passadas por valor ou por referência?
-
08-06-2019 - |
Pergunta
As variáveis PHP são passadas por valor ou por referência?
Solução
É por valor de acordo com o Documentação PHP.
Por padrão, os argumentos da função são passados por valor (de forma que se o valor do argumento dentro da função for alterado, ele não será alterado fora da função).Para permitir que uma função modifique seus argumentos, eles devem ser passados por referência.
Para que um argumento para uma função seja sempre passado por referência, acrescente um "e" comercial (&) ao nome do argumento na definição da função.
<?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.'
?>
Outras dicas
Parece que muitas pessoas ficam confusas com a maneira como os objetos são passados para funções e o que significa passar por referência.Variáveis de objeto ainda são passadas por valor, apenas o valor passado no PHP5 é um identificador de referência.Como prova:
<?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";
Saídas:
a, b
Para passar por referência significa que podemos modificar as variáveis que são vistas pelo chamador.O que claramente o código acima não faz.Precisamos mudar a função swap para:
<?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";
Saídas:
b, a
para passar por referência.
Em PHP, por padrão, os objetos são passados como cópia de referência para um novo objeto.
Veja este exemplo..........
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
Agora veja isso............
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.
Agora veja isso ............
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.
espero que você possa entender isso.
http://www.php.net/manual/en/migration5.oop.php
No PHP 5 existe um novo modelo de objetos.A manipulação de objetos do PHP foi completamente reescrita, permitindo melhor desempenho e mais recursos.Nas versões anteriores do PHP, os objetos eram tratados como tipos primitivos (por exemplo, inteiros e strings).A desvantagem desse método era que semanticamente todo o objeto era copiado quando uma variável era atribuída ou passado como parâmetro para um método.Na nova abordagem, os objetos são referenciados por identificador e não por valor (pode-se pensar em identificador como um identificador de objeto).
Variáveis PHP são atribuídas por valor, passadas para funções por valor e quando contêm/representam objetos são passadas por referência.Você pode forçar a passagem de variáveis por referência usando um &
Atribuído por exemplo de valor/referência:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
produziria
var1:teste, var2:teste final, var3:teste final
Aprovado por exemplo de valor/referência:
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
produziria:
var1:foo, var2 BAR
Variáveis de objeto passadas por exemplo de referência:
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";
}
Produziria:
FOO
(esse último exemplo provavelmente poderia ser melhor...)
Você pode passar uma variável para uma função por referência.Esta função será capaz de modificar a variável original.
Você pode definir a passagem por referência na definição da função:
<?php
function changeValue(&$var)
{
$var++;
}
$result=5;
changeValue($result);
echo $result; // $result is 6 here
?>
Você pode fazer isso de qualquer maneira.
coloque um símbolo '&' na frente e a variável que você está passando se tornará a mesma que sua origem.ou seja:você pode passar por referência, em vez de fazer uma cópia dela.
então
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
Variáveis contendo tipos primitivos são passadas por valor no PHP5.Variáveis contendo objetos são passadas por referência.Há um artigo bastante interessante do Linux Journal de 2006 que menciona esta e outras diferenças de OO entre 4 e 5.
Objetos são passados por referência no PHP 5 e por valor no PHP 4.As variáveis são passadas por valor por padrão!
Leia aqui: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
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() . "<br>";
echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";
Os atributos ainda podem ser modificados quando não são passados por referência, então tome cuidado.
Saída:
Trocar objetos:B, A Swapvalues:um, b
Na verdade, ambos os métodos são válidos, mas depende de sua necessidade. Passar valores por referência geralmente torna seu script lento.Portanto é melhor passar variáveis por valor considerando o tempo de execução.Além disso, o fluxo de código é mais consistente quando você passa variáveis por valor.
Use isto para funções quando desejar simplesmente alterar a variável original e retorná-la novamente para o mesmo nome de variável com seu novo valor atribuído.
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
Depende da versão, 4 é por valor, 5 é por referência.