PHP变量是按值还是按引用传递?

时间:2020-03-05 18:37:27  来源:igfitidea点击:

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

解决方案:

取决于版本,4是按值,5是按引用。

PHP变量按值分配,按值传递给函数,包含/表示对象时按引用传递。我们可以使用&强制变量按引用传递

通过值/参考示例分配:

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

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

将输出

var1: test, var2: final test, var3: final test

通过价值/参考书目:

$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

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

根据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.'
?>

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

In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or passed as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's identifier).

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

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

似乎很多人对对象传递给函数的方式以及引用所传递的方式感到困惑。对象变量仍然按值传递,它只是在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

为了通过引用。

我们可以采用任何一种方式来做。

在前面加上"&"符号,我们要传递的变量将与原点相同。即:我们可以通过引用传递,而不是复制它。

所以

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

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

在这里阅读: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>";

当未通过引用传递属性时,属性仍可修改,因此请注意。

输出:

交换对象:b,a
交换值:a,b