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

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

Are PHP Variables passed by value or by reference?

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


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

1
2
3
4
5
6
7
8
9
10
<?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.'
?>

似乎很多人对对象传递给函数的方式以及引用所传递的方式感到困惑。对象变量仍然按值传递,它只是在PHP5中传递的值是引用句柄。作为证明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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() ."
"
;

输出:

1
a, b

通过引用传递,我们可以修改调用者看到的变量。显然上面的代码不起作用。我们需要将交换功能更改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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() ."
"
;

输出:

1
b, a

为了通过引用。


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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.

我希望你能理解这一点。


http://www.php.net/manual/en/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).


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

通过值/参考示例分配:

1
2
3
4
5
6
7
$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

通过价值/参考书目:

1
2
3
4
5
6
7
8
9
10
11
$var1 ="foo";
$var2 ="bar";

changeThem($var1, $var2);

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

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

将输出:

var1: foo, var2 BAR

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

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


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

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

1
2
3
4
5
6
7
8
9
10
11
<?php
function changeValue(&$var)
{
    $var++;
}

$result=5;
changeValue($result);

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


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

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

所以

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

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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() ."";

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

输出:

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


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

在这里阅读:http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html


当您希望简单地更改原始变量,然后将其返回给分配了新值的相同变量名时,可将其用于函数。

1
2
3
4
5
6
7
8
9
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


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


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


推荐阅读