Mic*_*tum 288
它是根据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.'
?>
Run Code Online (Sandbox Code Playgroud)
har*_*dik 61
在PHP中,默认情况下,对象作为引用副本传递给新的Object.
看这个例子.............
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
Run Code Online (Sandbox Code Playgroud)
现在看这个..............
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.
Run Code Online (Sandbox Code Playgroud)
现在看这个..............
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.
Run Code Online (Sandbox Code Playgroud)
我希望你能理解这一点.
gro*_*rom 59
似乎很多人对对象传递给函数的方式以及通过引用传递的方式感到困惑.对象变量仍然按值传递,它只是在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";
Run Code Online (Sandbox Code Playgroud)
输出:
a, b
Run Code Online (Sandbox Code Playgroud)
为了按引用传递意味着我们可以修改由主叫方看到的变量.显然上面的代码没有做到.我们需要将交换功能更改为:
<?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";
Run Code Online (Sandbox Code Playgroud)
输出:
b, a
Run Code Online (Sandbox Code Playgroud)
为了通过引用传递.
Kar*_*uin 30
http://www.php.net/manual/en/migration5.oop.php
在PHP 5中有一个新的对象模型.PHP对对象的处理已经完全重写,允许更好的性能和更多的功能.在以前的PHP版本中,对象的处理方式与原始类型(例如整数和字符串)相同.这种方法的缺点是语义上整个对象在分配变量时被复制,或者作为参数传递给方法.在新方法中,对象由句柄引用,而不是由值引用(可以将句柄视为对象的标识符).
cmc*_*loh 25
PHP变量按值分配,按值传递给函数,并且包含/表示对象通过引用传递.您可以使用&强制变量通过引用传递
由值/参考示例分配:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
Run Code Online (Sandbox Code Playgroud)
会输出
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";
}
Run Code Online (Sandbox Code Playgroud)
输出:
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";
}
Run Code Online (Sandbox Code Playgroud)
输出:
FOO
(最后一个例子可能更好......)
TL;DR:PHP 支持按值传递和按引用传递。引用是使用与号 ( &) 声明的;这与 C++ 的做法非常相似。当函数的形式参数未使用 & 符号声明时(即,它不是引用),所有内容都按值传递,包括对象。对象和基元的传递方式没有区别。关键是要了解当您将对象传递给函数时传递的内容。这就是理解指针的价值所在。
对于将来遇到此问题的任何人,我想分享PHP 文档中的这个宝石,由匿名用户发布:
这里似乎有些混乱。指针和引用之间的区别并不是特别有帮助。已经发布的一些“全面”示例中的行为可以用更简单的统一术语来解释。例如,Hayley 的代码所做的正是您所期望的。(使用 >= 5.3)
第一个原则:指针存储访问对象的内存地址。每当分配一个对象时,都会生成一个指针。(我还没有深入研究 Zend 引擎,但据我所知,这适用)
第二个原则,也是最混乱的根源:默认情况下,将变量传递给函数是作为值传递完成的,即您正在使用副本。“但是对象是通过引用传递的!” 这是这里和 Java 世界中常见的误解。我从来没有说过什么的副本。默认传递是按值完成的。总是。然而,被复制和传递的是指针。当使用“->”时,您当然会访问与调用函数中的原始变量相同的内部结构。仅使用“=”只会播放副本。
第三个原则:“&”自动且永久地将另一个变量名称/指针设置为与其他内容相同的内存地址,直到您将它们解耦为止。这里使用术语“别名”是正确的。可以将其视为在臀部连接两个指针,直到用“unset()”强行分开。此功能既存在于同一作用域中,也存在于将参数传递给函数时。通常,传递的参数被称为“引用”,因为“按值传递”和“按引用传递”之间存在某些区别,这在 C 和 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.
}
?>
Run Code Online (Sandbox Code Playgroud)
我就 JavaScript 的这个主题写了一篇内容广泛、详细的博客文章,但我相信它同样适用于 PHP、C++ 以及人们似乎对按值传递和按引用传递感到困惑的任何其他语言。
显然,PHP 与 C++ 一样,是一种支持引用传递的语言。默认情况下,对象按值传递。当使用存储对象的变量时,将这些变量视为指针会有所帮助(因为这本质上就是它们在程序集级别的本质)。如果按值传递指针,您仍然可以“跟踪”该指针并修改所指向对象的属性。你不能做的是让它指向另一个对象。只有当您显式地将参数声明为通过引用传递时,您才能够做到这一点。
您可以通过引用将变量传递给函数.该函数将能够修改原始变量.
您可以在函数定义中通过引用定义段落:
<?php
function changeValue(&$var)
{
$var++;
}
$result=5;
changeValue($result);
echo $result; // $result is 6 here
?>
Run Code Online (Sandbox Code Playgroud)
你可以这样做.
在前面加上一个'&'符号,你传递的变量与它的原点相同.即:您可以通过引用传递,而不是复制它.
所以
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
Run Code Online (Sandbox Code Playgroud)
包含基本类型的变量在PHP5中按值传递。包含对象的变量通过引用传递。2006年《 Linux Journal》上有一篇有趣的文章,其中提到了4和5之间的这种差异以及其他面向对象的差异。
http://www.linuxjournal.com/article/9170