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


当前回答

关于如何将对象传递给函数,你仍然需要理解,没有“&”,你传递给函数的是一个对象句柄,对象句柄仍然是通过值传递的,它包含一个指针的值。但你不能改变这个指针,直到你通过引用传递它使用“&”

<?php
        class Example 
        {
            public $value;
         
        }
        
        function test1($x) 
        {
             //let's say $x is 0x34313131
             $x->value = 1;  //will reflect outsite of this function
                             //php use pointer 0x34313131 and search for the 
                             //address of 'value' and change it to 1

        }
        
        function test2($x) 
        {
             //$x is 0x34313131
             $x = new Example;
             //now $x is 0x88888888
             //this will NOT reflect outside of this function 
             //you need to rewrite it as "test2(&$x)"
             $x->value = 1000; //this is 1000 JUST inside this function
                 
        
        }
         
     $example = new Example;
    
     $example->value = 0;
    
     test1($example); // $example->value changed to  1
    
     test2($example); // $example did NOT changed to a new object 
                      // $example->value is still 1
     
 ?>

其他回答

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

PHP变量按值赋值,按值传递给函数,当包含/表示对象时通过引用传递。可以使用“&”强制变量通过引用传递。

由值/引用示例赋值:

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

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

输出:

Var1:测试,var2:最终测试,var3:最终测试

按值/引用示例传递:

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

changeThem($var1, $var2);

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

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

输出:

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

输出:

喷火

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

似乎很多人都对对象传递给函数的方式和引用传递的含义感到困惑。对象仍然是按值传递的,只是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

通过引用传递意味着我们可以修改调用者看到的变量,显然上面的代码没有做到这一点。我们需要将swap函数更改为:

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

为了通过引用传递。

关于如何将对象传递给函数,你仍然需要理解,没有“&”,你传递给函数的是一个对象句柄,对象句柄仍然是通过值传递的,它包含一个指针的值。但你不能改变这个指针,直到你通过引用传递它使用“&”

<?php
        class Example 
        {
            public $value;
         
        }
        
        function test1($x) 
        {
             //let's say $x is 0x34313131
             $x->value = 1;  //will reflect outsite of this function
                             //php use pointer 0x34313131 and search for the 
                             //address of 'value' and change it to 1

        }
        
        function test2($x) 
        {
             //$x is 0x34313131
             $x = new Example;
             //now $x is 0x88888888
             //this will NOT reflect outside of this function 
             //you need to rewrite it as "test2(&$x)"
             $x->value = 1000; //this is 1000 JUST inside this function
                 
        
        }
         
     $example = new Example;
    
     $example->value = 0;
    
     test1($example); // $example->value changed to  1
    
     test2($example); // $example did NOT changed to a new object 
                      // $example->value is still 1
     
 ?>

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