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)

  • @Obmerk如果你没有使用&符号来表示引用,那就不一定了.注意函数没有return语句,所以在你的情况下`$ str`将被赋值为null. (6认同)
  • 我也有这个疑问(新手) - 所以要明确一点,这就像`$ str = add_some_extra($ str);`如果我没有使用引用,对吧?那么真正的附加价值是什么? (4认同)
  • 真正的好处是你可以操纵/返回多个值.您还可以通过引用传递变量,并仍然让函数返回一些东西. (3认同)
  • 我想知道通过引用传递是否具有一些性能优势?我正在传递一个大数组,默认情况下它是按值传递的。那么,如果我使用引用调用,会有一些性能方面的好处吗???(整个过程中保持数组值不变) (2认同)
  • @Choxx没有任何需要通过引用传递数组来提高性能。PHP 引擎使用写时复制 - 它不会物理复制数组*除非*它在可见范围之一中被修改。然后它会制作一份副本,以便修改仅适用于一个地方。 (2认同)

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)

我希望你能理解这一点.

  • 这很好地说明了 PHP 对象句柄是如何工作的。 (2认同)
  • 第1个ex,obj的引用值传递给函数,使用new引用更改为obj将反映到指向同一个obj的所有其他引用.第2个ex,再次将obj的引用的VALUE传递给函数,该函数将引用的值更改为指向新的obj,旧的obj保持不变.第3个例子,obj的引用值的引用被传递给函数,因此函数的变化在同一个obj上运行. (2认同)

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)

为了通过引用传递.

  • 我认为这个证据是一种误解.看起来你试图交换引用.您对如何分配对象有疑问.您正在重新分配不可变的引用.这是它可以从内部改变的价值.交换的重新定义现在传递**x,允许您更改*x.问题是认为$ x = $ y会改变$ x最初指向的内容. (16认同)
  • *这不是证据*.如果将整个对象的当前值传递给`swap`函数,那么第一个例子的输出正是你所期望的; 换句话说,如果对象是"按值传递".另一方面,如果将对象句柄传递给函数,它也正是您所期望的,实际上会发生这种情况.您的代码不区分这两种情况. (7认同)

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

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

  • “对象”不是PHP5中的值,因此不能“传递”。$ foo的值是*指向对象的指针*。$ foo被值传递给函数changeFoo(),因为changeCoo()没有用&声明其参数。 (2认同)

Ale*_*drH 9

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++ 一样,是一种支持引用传递的语言。默认情况下,对象按值传递。当使用存储对象的变量时,将这些变量视为指针会有所帮助(因为这本质上就是它们在程序集级别的本质)。如果按值传递指针,您仍然可以“跟踪”该指针并修改所指向对象的属性。你不能做的是让它指向另一个对象。只有当您显式地将参数声明为通过引用传递时,您才能够做到这一点。


Mah*_*sin 8

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

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

<?php
function changeValue(&$var)
{
    $var++;
}

$result=5;
changeValue($result);

echo $result; // $result is 6 here
?>
Run Code Online (Sandbox Code Playgroud)


Bin*_*ngy 6

你可以这样做.

在前面加上一个'&'符号,你传递的变量与它的原点相同.即:您可以通过引用传递,而不是复制它.

所以

    $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)

  • 这已被弃用并生成警告 (2认同)

Pol*_*nby 5

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

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