PHP变量是按值传递还是按引用传递?
当前回答
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";
}
输出:
喷火
(最后一个例子可能更好。)
其他回答
根据PHP文档,它是按值计算的。
默认情况下,函数实参是按值传递的(这样,如果函数内实参的值改变了,它不会在函数外被改变)。为了允许函数修改其参数,它们必须通过引用传递。 要让函数的实参始终通过引用传递,请在函数定义中的实参名称前加上&。
<?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/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变量按值赋值,按值传递给函数,当包含/表示对象时通过引用传递。可以使用“&”强制变量通过引用传递。
由值/引用示例赋值:
$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";
}
输出:
喷火
(最后一个例子可能更好。)
TL;DR: PHP supports both pass by value and pass by reference. References are declared using an ampersand (&); this is very similar to how C++ does it. When the formal parameter of a function is not declared with an ampersand (i.e., it's not a reference), everything is passed by value, including objects. There is no distinction between how objects and primitives are passed around. The key is to understand what gets passed along when you pass in objects to a function. This is where understanding pointers is invaluable.
对于将来遇到这种情况的人,我想分享这个来自PHP文档的精华,由一位匿名用户发布:
这里似乎有些混乱。指针和引用之间的区别并不是特别有用。 已经发布的一些“综合”示例中的行为可以用更简单的统一术语来解释。例如,Hayley的代码正在做您应该期望它应该做的事情。(使用>= 5.3)
第一个原则: 指针存储访问对象的内存地址。任何时候赋值一个对象,都会生成一个指针。(我还没有深入研究Zend引擎,但据我所知,这是适用的)
2nd principle, and source of the most confusion: Passing a variable to a function is done by default as a value pass, ie, you are working with a copy. "But objects are passed by reference!" A common misconception both here and in the Java world. I never said a copy OF WHAT. The default passing is done by value. Always. WHAT is being copied and passed, however, is the pointer. When using the "->", you will of course be accessing the same internals as the original variable in the caller function. Just using "=" will only play with copies.
3rd principle: "&" automatically and permanently sets another variable name/pointer to the same memory address as something else until you decouple them. It is correct to use the term "alias" here. Think of it as joining two pointers at the hip until forcibly separated with "unset()". This functionality exists both in the same scope and when an argument is passed to a function. Often the passed argument is called a "reference," due to certain distinctions between "passing by value" and "passing by reference" that were clearer in C and C++.
只要记住:传递给函数的是指向对象的指针,而不是对象本身。这些指针是原始指针的副本,除非在参数列表中使用“&”来实际传递原始指针。只有当你深入到一个物体的内部时,原始的东西才会改变。
下面是他们提供的例子:
<?php
//The two are meant to be the same
$a = "Clark Kent"; //a==Clark Kent
$b = &$a; //The two will now share the same fate.
$b="Superman"; // $a=="Superman" too.
echo $a;
echo $a="Clark Kent"; // $b=="Clark Kent" too.
unset($b); // $b divorced from $a
$b="Bizarro";
echo $a; // $a=="Clark Kent" still, since $b is a free agent pointer now.
//The two are NOT meant to be the same.
$c="King";
$d="Pretender to the Throne";
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByValue($c, $d);
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByRef($c, $d);
echo $c."\n"; // $c=="Pretender to the Throne"
echo $d."\n"; // $d=="King"
function swapByValue($x, $y){
$temp=$x;
$x=$y;
$y=$temp;
//All this beautiful work will disappear
//because it was done on COPIES of pointers.
//The originals pointers still point as they did.
}
function swapByRef(&$x, &$y){
$temp=$x;
$x=$y;
$y=$temp;
//Note the parameter list: now we switched 'em REAL good.
}
?>
关于JavaScript的这个主题,我写了一篇广泛而详细的博客文章,但我相信它同样适用于PHP、c++和任何其他人们似乎对按值传递和按引用传递感到困惑的语言。
Clearly, PHP, like C++, is a language that does support pass by reference. By default, objects are passed by value. When working with variables that store objects, it helps to see those variables as pointers (because that is fundamentally what they are, at the assembly level). If you pass a pointer by value, you can still "trace" the pointer and modify the properties of the object being pointed to. What you cannot do is have it point to a different object. Only if you explicitly declare a parameter as being passed by reference will you be able to do that.
两种方法都可以。
在前面放一个“&”符号,你传递的变量就变成了它的原点,也就是说,你可以通过引用传递,而不是复制它。
so
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
推荐文章
- PHP中接口的意义是什么?
- 致命错误:未找到类“SoapClient”
- 我目前使用的是哪个版本的CodeIgniter ?
- 合并两个PHP对象的最佳方法是什么?
- 如何使HTTP请求在PHP和不等待响应
- 发送附件与PHP邮件()?
- 如何获得当前的路线在Symfony 2?
- 用PHP删除字符串的前4个字符
- mysql_connect():[2002]没有这样的文件或目录(试图通过unix:///tmp/mysql.sock连接)在
- 一个函数的多个返回值
- 在PHP中使用foreach循环时查找数组的最后一个元素
- 检查数组是否为空
- PHP DOMDocument loadHTML没有正确编码UTF-8
- PHP在个位数数前加上前导零
- PHPMailer字符编码问题