São variáveis ​​PHP passados ​​por valor ou por referência?

votos
174

São variáveis ​​PHP passados ​​por valor ou por referência?

Publicado 03/08/2008 em 21:51
fonte usuário
Em outras línguas...                            


14 respostas

votos
-6

Depende da versão, 4 é de valor, é 5 por referência.

Respondeu 03/08/2008 em 21:52
fonte usuário

votos
19

PHP variáveis ​​são atribuídos pelo valor, passado para funções por valor, e quando contendo / objectos representativas são passados ​​por referência. Você pode forçar variáveis ​​para passar por referência usando um &

Atribuído por exemplo valor / referência:

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

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

saída seria

var1: teste, var2: teste final, var3: teste final

Passados ​​por exampe valor / referência:

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

changeThem($var1, $var2);

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

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

saída seria:

var1: foo, BAR var2

Objecto variáveis ​​passaram por exampe 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";
}

Saída seria:

FOO

(Esse último exemplo poderia ser melhor, provavelmente, ...)

Respondeu 03/08/2008 em 21:52
fonte usuário

votos
215

É por valor de acordo com a documentação PHP .

Por padrão, argumentos de função são passados ​​por valor (de modo que, se o valor do parâmetro dentro da função for alterado, ele não fica alterado fora da função). Para permitir que uma função modifique seus argumentos, eles devem ser passados ​​por referência.

Para ter um argumento para uma função sempre passados por referência, preceder um e comercial ( & ) para o 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.'
?>
Respondeu 03/08/2008 em 22:06
fonte usuário

votos
24

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

No PHP 5 há um novo modelo de objeto. manipulação de objetos do PHP foi totalmente reescrito, permitindo melhor desempenho e mais recursos. Em versões anteriores do PHP, objectos foram tratadas como tipos de primitivas (por exemplo, números inteiros e cadeias de caracteres). A desvantagem deste método é que semanticamente todo o objecto foi copiado quando uma variável foi atribuído, ou transmitido como um parâmetro para um método. Na nova abordagem, os objetos são referenciados pelo punho, e não por valor (pode-se pensar em uma alça como identificador de um objeto).

Respondeu 03/08/2008 em 22:57
fonte usuário

votos
4

Variáveis ​​que contêm tipos de primitivas são passados ​​por valor em PHP5. Variáveis ​​que contenham objectos são passados ​​por referência. Há bastante um interessante artigo de Linux Journal a partir de 2006 que menciona esta e outras diferenças OO entre 4 e 5.

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

Respondeu 03/08/2008 em 23:05
fonte usuário

votos
52

Parece um monte de pessoas ficam confusas com a forma como os objetos são passados ​​para funções e que passa por meio de referência. variáveis ​​de objeto ainda são passados ​​por valor, é apenas o valor que é passado em 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 vistos pelo chamador. 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

a fim de passar por referência.

Respondeu 11/08/2008 em 01:09
fonte usuário

votos
5

Você pode fazê-lo de qualquer maneira.

colocar um símbolo '&' na frente e a variável que você está passando torna-se uma ea mesma coisa como a sua origem. ou seja: você pode passar por referência, ao invés de fazer uma cópia do mesmo.

assim

    $fred = 5;
    $larry = & $fred;
    $larry = 8;
    echo $fred;//this will output 8, as larry and fred are now the same reference.
Respondeu 22/02/2009 em 08:17
fonte usuário

votos
1

Os objetos são passados ​​por referência em PHP 5 e por valor em PHP 4. Variáveis ​​são passados ​​por valor por padrão!

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

Respondeu 09/01/2010 em 15:34
fonte usuário

votos
1
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>";

Atributos ainda são modificáveis ​​quando não passado por referência por isso tome cuidado.

Saída:

SwapObjects: b, um SwapValues: a, b

Respondeu 11/05/2010 em 14:51
fonte usuário

votos
37

Em PHP, por objetos padrão são passados ​​como cópia de referência a 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.

Respondeu 14/03/2012 em 04:09
fonte usuário

votos
7

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
?>
Respondeu 21/12/2014 em 07:27
fonte usuário

votos
0

Na verdade, ambos os métodos são válidos, mas depende de seus valores requirement.Pass por referência muitas vezes faz o seu script lento. Então é melhor passar variáveis ​​por valor, considerando o tempo de execução. Além disso, o fluxo de código é mais consistente quando você passar variáveis ​​por valor.

Respondeu 15/07/2015 em 10:25
fonte usuário

votos
0

Utilize este para funções quando quiser simplesmente alterar a variável original e devolvê-lo novamente para o mesmo nome de variável com o seu novo valor atribuído.

function add(&$var){ // The &amp; 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
Respondeu 31/03/2018 em 11:34
fonte usuário

votos
0

Para quem se depara com isso no futuro, eu quero compartilhar esta jóia dos docs PHP, postado por um usuário anônimo :

Parece haver alguma confusão aqui. A distinção entre ponteiros e referências não é particularmente útil. O comportamento em alguns dos "globais" exemplos já postados pode ser explicada em termos de unificação mais simples. código de Hayley, por exemplo, está fazendo exatamente o que você deve esperar que deveria. (Usando> = 5,3)

Primeiro princípio: ponteiro armazena um um endereço de memória para acessar um objeto. Qualquer vez que um objecto é atribuído, um ponteiro é gerada. (Eu não mergulhou tão profundamente no motor Zend ainda, mas tanto quanto eu posso ver, isso se aplica)

2º princípio e fonte da mais confusão: Passando uma variável para uma função é feito por padrão como um passe de valor, ou seja, você está trabalhando com uma cópia. "Mas os objetos são passados ​​por referência!" Um equívoco comum, tanto aqui como no mundo Java. Eu nunca disse uma cópia do que. A passagem padrão é feita por valor. Sempre. O que está sendo copiado e passado, no entanto, é o ponteiro. Ao usar o "->", você vai, naturalmente, ser acessando os mesmos internos como a variável original na função de chamada. Basta usar "=" só vai jogar com cópias.

3º princípio: "&" automática e permanentemente define outro nome / ponteiro variável para o mesmo endereço de memória como algo mais até que você dissociar-los. É correto usar o termo "apelido" aqui. Pense-lo como a junção de dois ponteiros no quadril até à força separadas com "unset ()". Esta funcionalidade existe tanto no mesmo alcance e quando um argumento é passado para uma função. Muitas vezes, o argumento passado é chamado de "referência", devido a certas distinções entre "passando pelo valor" e "passagem por referência" que foram mais clara em C e C ++.

Basta lembrar: ponteiros para objetos, e não os próprios objetos, são passados ​​para funções. Estes ponteiros são cópias do original, a menos que você use "&" em sua lista de parâmetro para realmente passar os originais. Somente quando você cavar a parte interna de um objeto vão os originais mudar.

E aqui está o exemplo que eles fornecem:

<?php

//The two are meant to be the same
$a = "Clark Kent"; //a==Clark Kent
$b = &$a; //The two will now share the same fate.

$b="Superman"; // $a=="Superman" too.
echo $a;
echo $a="Clark Kent"; // $b=="Clark Kent" too.
unset($b); // $b divorced from $a
$b="Bizarro";
echo $a; // $a=="Clark Kent" still, since $b is a free agent pointer now.

//The two are NOT meant to be the same.
$c="King";
$d="Pretender to the Throne";
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByValue($c, $d);
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByRef($c, $d);
echo $c."\n"; // $c=="Pretender to the Throne"
echo $d."\n"; // $d=="King"

function swapByValue($x, $y){
$temp=$x;
$x=$y;
$y=$temp;
//All this beautiful work will disappear
//because it was done on COPIES of pointers.
//The originals pointers still point as they did.
}

function swapByRef(&$x, &$y){
$temp=$x;
$x=$y;
$y=$temp;
//Note the parameter list: now we switched 'em REAL good.
}

?>

I escreveu um extenso, pós detalhado blog sobre este assunto para Java , mas eu acredito que se aplica igualmente bem para PHP, C ++, e qualquer outra língua, onde as pessoas parecem estar confuso sobre passagem by pass valor vs. por referência.

Claramente, PHP, como C ++, é uma linguagem que faz passagem apoio por referência. Por padrão, os objetos são passados ​​por valor. Ao trabalhar com variáveis ​​que armazenam objetos, ele ajuda a ver essas variáveis ​​como ponteiros (porque isso é fundamentalmente o que são, no nível da montagem). Se você passar um ponteiro por valor, você ainda pode "trace" o ponteiro e modificar as propriedades do objeto que está sendo apontado. O que você não pode fazer é tê-lo apontar para um objeto diferente. Só se você declarar explicitamente um parâmetro como sendo passada por referência, você será capaz de fazer isso.

Respondeu 05/02/2020 em 20:22
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more