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

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

13 ответов


это по значению в соответствии с документация 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.'
?>

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

Я надеюсь, вы можете понять это.


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

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


переменные PHP назначаются по значению, передаются функциям по значению, а при содержании / представлении объектов передаются по ссылке. Вы можете заставить переменные проходить по ссылке с помощью &

присваивается значение/пример:

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

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

выводит

var1: тест, var2: окончательный тест, var3: окончательный тест

прошло по значению / ссылка exampe:

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

changeThem($var1, $var2);

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

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

выводит:

var1: foo, var2 BAR

объектные переменные, переданные по ссылке exampe:

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
function changeValue(&$var)
{
    $var++;
}

$result=5;
changeValue($result);

echo $result; // $result is 6 here
?>

вы можете сделать это в любом случае.

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

так

    $fred = 5;
    $larry = & $fred;
    $larry = 8;
    echo $fred;//this will output 8, as larry and fred are now the same reference.

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

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


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

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


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


на самом деле оба метода действительны, но это зависит от вашего требования.Передача значений по ссылке часто замедляет работу скрипта. Поэтому лучше передавать переменные по значению, учитывая время выполнения. Также поток кода более последователен, когда вы передаете переменные по значению.


используйте это для функций, когда вы хотите просто изменить исходную переменную и вернуть ее снова в то же имя переменной с назначенным новым значением.

function add(&$var){ // The &amp; is before the argument $var
   $var++;
}
$a = 1;
$b = 10;
add($a);
echo "a is $a,";
add($b);
echo " a is $a, and b is $b"; // Note: $a and $b are NOT referenced

зависит от версии, 4 по значению, 5 по ссылке.