PHP变量是通过值还是通过引用传递的?

PHP变量是通过值还是通过引用传递的?

0
额外 编辑
意见: 1
额外 作者 nawfal,

13 答案

PHP variables are assigned by value, passed to functions by value, and when containing/representing objects are passed by reference. You can force variables to pass by reference using an &

按值/参考示例分配:

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

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

会输出

var1:test,var2:最终测试,var3:最终测试

通过价值/参考实例:

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

changeThem($var1, $var2);

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

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

会输出:

var1:foo,var2 BAR

通过引用实例传递的对象变量:

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

会输出:

FOO

(最后一个例子可能会更好......)

0
额外
“对象”在PHP5中不是值,不能被“传递”。 $ foo 的值是指向一个对象的指针。因为 changeFoo()没有声明它的参数,因此 $ foo 被值</ b​​>传递给函数 changeFoo()
额外 作者 newacct,

它的价值根据 PHP文档

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition.

<?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.'
?>
0
额外
我也有这个疑问(新手) - 所以只需要清楚,这将与 $ str = add_some_extra($ str); 相同,如果我不使用引用,对吧?那么真正的附加价值是什么?
额外 作者 Obmerk Kronen,
@Obmerk如果你不使用&符号来表示引用,它不会是等价的。注意函数没有返回语句,所以在你的情况下, $ str 将被赋值为null。
额外 作者 Kimberly W,
如果你这样做@ObmerkKronen,那么你将不得不返回值并通过你的代码抓住它。否则初始变量将保持不变。
额外 作者 Nabeel Khan,
我想知道通过引用是否有一些性能优势?我传递一个大数组,默认情况下它是按值传递的。所以,如果我通过参考使用呼叫,那么会有一些性能明智的好处吗? (在整个过程中保持数组值不变)
额外 作者 Choxx,
真正的好处是你可以操纵/返回多个值。你也可以通过引用传递变量,并让函数返回一些东西。
额外 作者 MA-Maddin,

包含原始类型的变量在PHP5中按值传递。包含对象的变量通过引用传递。 Linux Journal从2006年开始提供了一篇非常有趣的文章,其中提到了4和5之间的这种差异和其他OO差异。

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

0
额外
如果函数的参数没有,则所有变量都通过PHP中的值传递。
额外 作者 newacct,

似乎有很多人被对象传递给函数的方式以及通过引用方式传递的方式弄糊涂了。对象变量仍然按值传递,它只是在PHP5中传递的值是引用句柄。作为证明:

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

输出:

a, b

传递引用意味着我们可以修改调用者看到的变量。上面的代码显然没有这样做。我们需要将交换功能更改为:

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

输出:

b, a

以通过参考传递。

0
额外
这不是一个证明。如果将整个对象的当前值传递给 swap 函数,那么第一个示例的输出正如您所期望的那样;换句话说,如果对象是“按价值传递”的。另一方面,如果一个对象句柄被传递给函数,这也正是你所期望的,这实际上是发生了什么。你的代码不区分这两种情况。
额外 作者 EML,
我认为这个证据是一个误解。它看起来像你试图交换引用。您在分配对象方面遇到问题。您正在重新分配不可变的参考。它指向的价值可以从内部改变。交换的重新定义现在通过** x,这允许您更改* x。问题在于认为$ x = $ y会改变$ x原来的指向。
额外 作者 grantwparks,

取决于版本,4是值,5是参考。

0
额外
我不认为这是真的。
额外 作者 Nick Heiner,

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

在PHP 5中有一个新的对象模型。 PHP的对象处理已经完全重写,可以获得更好的性能和更多的功能。在以前的PHP版本中,对象被处理为基本类型(例如整数和字符串)。这种方法的缺点是,在分配变量或作为参数传递给方法时,会在语义上复制整个对象。在新方法中,对象由句柄引用,而不是由值引用(可以将句柄视为对象的标识符)。
0
额外

在PHP中,默认情况下,对象作为参考副本传递给新对象。

看到这个例子.............

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

现在看到这个..............

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.

现在看到这个..............

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.

我希望你能理解这一点。

0
额外
第一个ex,obj的引用值被传递给函数,使用新引用改变为obj将反映到指向同一obj的所有其他引用。第二个ex,再次将obj的引用的VALUE传递给该函数,该函数将引用的值更改为指向新的obj,旧的obj保持不变。第3个例子中,obj的引用值的引用被传递给函数,因此函数中的变化在相同的obj上运行。
额外 作者 s-hunter,
这很好地说明了PHP对象如何处理工作。
额外 作者 Frederik Krautwald,

您可以通过引用将变量传递给函数。该功能将能够修改原始变量。

您可以在函数定义中通过引用来定义段落:

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

$result=5;
changeValue($result);

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

如果您希望简单地更改原始变量并将其重新返回到指定了新值的相同变量名称,请将其用于函数。

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
0
额外

你可以这样做。

put a '&' symbol in front and the variable you are passing becomes one and the same as its origin. ie: you can pass by reference, rather than making a copy of it.

所以

    $fred = 5;
    $larry = & $fred;
    $larry = 8;
    echo $fred;//this will output 8, as larry and fred are now the same reference.
0
额外
这已被弃用并产生警告
额外 作者 fijiaaron,

对象在PHP 5中通过引用传递,在PHP 4中通过值传递。 变量按默认值传递!

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

0
额外
“对象”在PHP5中不是值,不能被“传递”。如果传递给函数的参数没有,则所有变量都通过值传递。
额外 作者 newacct,
@FélixGagnon-Grenier:同样,“对象”不是价值观,不能被“传递”。 PHP5中不能有一个“变量”,它的值是一个“对象”,只能有一个值作为对象引用(即指向对象的指针)。当然,您可以通过值传递或指定一个指向对象的指针,并通过调用执行此类修改的方法来修改它指向的对象。这与通过引用无关。什么类型的值以及参数是按值传递还是按引用传递是独立的和正交的事情。
额外 作者 newacct,
@newacct不完全?对象是有点传递参考。我想我已经观察到,即使在定义中的参数之前没有用定义的函数,php对象也可以被函数修改 - 如果它们是通过值传递的,它作为参数的功能不会受到影响。
额外 作者 Félix Gagnon-Grenier,
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() . "
"; echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "
";

当不通过引用传递时,属性仍然可以修改,所以要小心。

输出:

SwapObjects:b,a SwapValues:a,b

0
额外

实际上这两种方法都是有效的,但它取决于您的要求。通过引用来传递值通常会使您的脚本变慢。因此,考虑到执行时间,最好通过值来传递变量。当您按值传递变量时,代码流更加一致。

0
额外