Переменные PHP передаются по значению или по ссылке? - PullRequest
212 голосов
/ 04 августа 2008

Передаются ли переменные PHP по значению или по ссылке?

Ответы [ 13 ]

271 голосов
/ 04 августа 2008

Это по значению согласно 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.'
?>
58 голосов
/ 11 августа 2008

Кажется, многие люди смущаются тем, как объекты передаются в функции и что означает передача по ссылке. Переменные объекта по-прежнему передаются по значению, просто значение, переданное в 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

To передать по ссылке означает, что мы можем изменить переменные, которые видит вызывающая сторона. Который явно код выше не делает. Нам нужно изменить функцию подкачки на:

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

чтобы перейти по ссылке.

51 голосов
/ 14 марта 2012

В PHP объекты по умолчанию передаются в качестве эталонной копии новому объекту.

См. Этот пример .............

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

Теперь посмотри на это ..............

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.

Теперь посмотри на это ..............

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.

Надеюсь, вы понимаете это.

28 голосов
/ 04 августа 2008

http://www.php.net/manual/en/migration5.oop.php

В PHP 5 появилась новая объектная модель. Обработка объектов в PHP была полностью переписана, что позволило повысить производительность и расширить возможности. В предыдущих версиях PHP объекты обрабатывались как примитивные типы (например, целые числа и строки). Недостаток этого метода состоял в том, что семантически весь объект копировался при присвоении переменной или передавался в качестве параметра методу. В новом подходе на объекты ссылаются по дескриптору, а не по значению (можно рассматривать дескриптор как идентификатор объекта).

21 голосов
/ 04 августа 2008

Переменные 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";
}

выдаст:

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

Будет выводить:

FOO

(последний пример мог бы быть лучше ...)

7 голосов
/ 21 декабря 2014

Вы можете передать переменную в функцию по ссылке. Эта функция сможет изменять исходную переменную.

Вы можете определить проход по ссылке в определении функции:

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

$result=5;
changeValue($result);

echo $result; // $result is 6 here
?>
5 голосов
/ 22 февраля 2009

Вы можете сделать это любым способом.

поместите символ '&' впереди, и передаваемая вами переменная станет одной и той же, что и ее источник. то есть: вы можете передавать по ссылке, а не делать копию.

так

    $fred = 5;
    $larry = & $fred;
    $larry = 8;
    echo $fred;//this will output 8, as larry and fred are now the same reference.
4 голосов
/ 04 августа 2008

Переменные, содержащие примитивные типы, передаются по значению в PHP5. Переменные, содержащие объекты, передаются по ссылке. В журнале Linux за 2006 год есть довольно интересная статья, в которой упоминается эта и другие различия между 4 и 5.

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

1 голос
/ 11 мая 2010
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() . "<br>";

echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";

Атрибуты по-прежнему можно изменять, если они не переданы по ссылке, поэтому будьте осторожны.

Выход:

SwapObjects: b, a SwapValues: a, b

1 голос
/ 09 января 2010

Объекты передаются по ссылке в PHP 5 и по значению в PHP 4. Переменные передаются по значению по умолчанию!

Читайте здесь: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html

...