2008-08-03 17 views

Respuesta

207

Es por valor de acuerdo con la PHP Documentation.

De manera predeterminada, los argumentos de las funciones se pasan por valor (de modo que si se cambia el valor del argumento dentro de la función, no se cambia fuera de la función). Para permitir que una función modifique sus argumentos, se deben pasar por referencia.

Para tener un argumento a una función siempre pasado por referencia, anteponer un ampersand (&) a nombre del parámetro en la definición de función.

<?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.' 
?> 
+4

También tuve esta duda (novato) - así que para ser claro, esto sería lo mismo que '$ str = add_some_extra ($ str);' si no estuviera usando la referencia, ¿no? entonces, ¿cuál es el verdadero valor agregado de eso? –

+3

@Obmerk Si no estabas usando el ampersand para significar por referencia, no sería equivalente. Observe cómo la función no tiene declaración de retorno, por lo que '$ str' se le asignaría nulo, en su caso. –

+0

si lo haces de esta manera @ObmerkKronen, entonces tendrás que devolver el valor y atraparlo a través de tu código también. La variable inicial seguirá siendo la misma de lo contrario. –

-6

Depende de la versión, 4 es por valor, 5 es por referencia.

+8

No creo que esto sea cierto. –

17

Las variables de PHP se asignan por valor, se pasan a las funciones por valor y al contener/representar objetos se pasan por referencia. Puede forzar las variables que pasar por referencia utilizando un &

Asignado por ejemplo valor/referencia:

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

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

emitiría

var1: prueba, var2: prueba final, var3: prueba final

Pasado por exampe valor/referencia:

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

changeThem($var1, $var2); 

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

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

seria:

var1: foo, var2 BAR

variables de objeto pasado por exampe referencia: salida

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"; 
} 

Would:

FOO

(ese último ejemplo podría ser mejor, probablemente, ...)

+0

"Objetos" no son valores en PHP5 y no pueden "pasarse". El valor de '$ foo' es un puntero * a un objeto *. '$ foo' está ** pasado por valor ** a la función' changeFoo() ', ya que' changeFoo() 'no declaró su parámetro con un' & '. – newacct

23

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

En PHP 5 hay un nuevo modelo de objetos. El manejo de objetos por PHP ha sido completamente reescrito, lo que permite un mejor rendimiento y más funciones. En versiones anteriores de PHP, los objetos se manejaban como tipos primitivos (por ejemplo, enteros y cadenas). El inconveniente de este método era que semánticamente todo el objeto se copiaba cuando se asignaba una variable, o se pasaba como un parámetro a un método. En el nuevo enfoque, los objetos se referencian por manejador, y no por valor (se puede pensar en un manejador como el identificador de un objeto).

4

Las variables que contienen tipos primitivos se pasan por valor en PHP5. Las variables que contienen objetos se pasan por referencia. Hay bastante un interesante artículo de Linux Journal de 2006, que menciona esta y otras diferencias OO entre 4 y 5.

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

+0

Todas las variables se pasan por valor en PHP si el parámetro de la función no tiene '&'. – newacct

51

Parece que mucha gente se confunda por la forma en que los objetos son pasados ​​a las funciones y lo que pase por medios de referencia. Las variables de objeto aún se pasan por valor, solo el valor que se pasa en PHP5 es un identificador de referencia. Como prueba:

<?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"; 

Salidas:

a, b 

Para pass by reference significa que podemos modificar las variables que son vistos por la persona que llama. Que claramente el código anterior no funciona. Tenemos que cambiar la función de intercambio 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"; 

Salidas:

b, a 

el fin de pasar por referencia.

+11

Creo que esta prueba es una interpretación errónea. Parece que estabas tratando de intercambiar referencias. Usted tiene un problema con la forma en que se asignan los objetos. Está reasignando la referencia que es inmutable. Es el valor que apunta a que se puede cambiar desde adentro. La redefinición de swap ahora está pasando ** x, lo que le permite cambiar * x. El problema está en pensar que $ x = $ y cambiaría lo que originalmente apunta $ x. – grantwparks

+3

* Esto no es una prueba *. La salida del primer ejemplo es exactamente lo que esperaría si el valor actual de todo el objeto se pasa a la función 'swap'; en otras palabras, si los objetos fueron "pasados ​​por valor". Por otro lado, también es exactamente lo que esperarías si se pasara un control de objeto a la función, que en realidad es lo que sucede. Su código no distingue entre estos dos casos. – EML

5

Puede hacerlo de cualquier manera.

coloque un símbolo '&' al frente y la variable que está pasando se convierte en una sola y su origen. es decir: puede pasar por referencia, en lugar de hacer una copia de la misma.

por lo

$fred = 5; 
    $larry = & $fred; 
    $larry = 8; 
    echo $fred;//this will output 8, as larry and fred are now the same reference. 
+2

Esto está en desuso y genera una advertencia – fijiaaron

1

objetos se pasan por referencia en PHP 5 y por el valor en PHP 4. Las variables se pasan por valor por defecto!

leer aquí: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html

+0

"Objetos" no son valores en PHP5 y no se pueden "pasar". Todas las variables se pasan por valor si el parámetro de la función pasada no tiene '&'. – newacct

+0

@newacct no del todo? Los objetos son [algo pasado por referencia] (http://php.net/manual/en/language.oop5.references.php). Creo que he observado que los objetos php pueden ser modificados por funciones incluso cuando no están definidos con '&' delante de los parámetros en la definición, si se pasaron por valor el objeto contenido en el alcance que llamó a la función como un parámetro no se vería afectado. –

+2

@ FélixGagnon-Grenier: Nuevamente, los "objetos" no son valores y no pueden "pasarse". No puede tener una "variable" en PHP5 cuyo valor sea un "objeto", solo puede tener un valor que sea una referencia de objeto (es decir, un puntero a un objeto). Por supuesto, puede pasar o asignar un puntero a un objeto por valor y modificar el objeto al que apunta llamando a un método que realice dicha modificación. Eso no tiene nada que ver con pasar por referencia. Qué tipo es un valor y si un parámetro es pass-by-value/pass-by-reference son cosas independientes y ortogonales. – newacct

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

Los atributos son todavía modificable cuando no se pasa por referencia así que cuidado.

de salida:

SwapObjects: B, A SwapValues: A, B

36

En PHP, por objetos predeterminados se pasa como copia de referencia a un nuevo objeto.

Ver este ejemplo .............

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 

Ahora ven esto ..............

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. 

Ahora ven esto ..............

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 puedan entender esto.

+0

Esto ilustra muy bien cómo funciona el objeto PHP. –

+0

1st ex, el valor de la referencia del obj se pasa a la función, los cambios en el obj usando la nueva referencia se reflejarán en todas las demás referencias que apunten al mismo obj.2º ex, nuevamente el VALOR de la referencia del obj se pasa a la función, la función cambia el valor de la referencia para apuntar a un nuevo obj, el obj viejo permanece igual. 3º ex, la referencia del valor de la referencia del obj pasa a la función, por lo que los cambios en la función operan en el mismo obj. –

7

Puede pasar una variable a una función por referencia.Esta función podrá modificar la variable original.

Se puede definir el paso por referencia en la definición de función:

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

$result=5; 
changeValue($result); 

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

En realidad ambos métodos son válidos, pero depende de sus valores requirement.Pass por referencia a menudo hace que su escritura lenta. Entonces es mejor pasar variables por valor considerando el tiempo de ejecución. Además, el flujo de código es más consistente cuando pasa variables por valor.

Cuestiones relacionadas