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

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

3.08.2008 22:51:41
хорошее объяснение в codeexpertz.com/blog/php/…
Premlatha 2.04.2019 08:38:10
14 ОТВЕТОВ
РЕШЕНИЕ

Это по стоимости в соответствии с документацией 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.'
?>
306
5.07.2016 10:56:14
У меня также было это сомнение (новичок) - так что для ясности, это было бы так же, как $str = add_some_extra($str);если бы я не использовал ссылку, верно? тогда какова реальная добавленная стоимость этого?
Obmerk Kronen 24.11.2013 06:06:01
@Obmerk Если вы не используете амперсанд для обозначения по ссылке, это не будет эквивалентно. Обратите внимание, что функция не имеет оператора возврата, поэтому $strв вашем случае ей будет присвоен ноль.
The Unknown Dev 22.01.2015 19:31:39
если вы сделаете это таким образом @ObmerkKronen, то вам придется вернуть значение и перехватить его через ваш код. В противном случае исходная переменная останется прежней.
Nabeel Khan 4.04.2016 20:54:31
Мне интересно, если передача по ссылке имеет некоторые преимущества в производительности или нет? Я передаю большой массив и по умолчанию он передается по значению. Так что, если я использую вызов по ссылке, будет ли некоторое преимущество в производительности ??? (сохранение значений массива в течение всего процесса)
Choxx 8.10.2016 05:31:34
реальная выгода в том, что вы можете манипулировать / возвращать несколько значений. Вы также можете передавать переменные по ссылке и при этом позволить функции возвращать что-то.
Martin Schneider 18.06.2017 13:21:56

В 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.

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

62
14.03.2012 06:09:47
Это очень хорошо иллюстрирует, как работает PHP-объект.
Frederik Krautwald 1.11.2014 09:56:07
1-й пример, значение ссылки на объект передается в функцию, изменения в объекте с использованием новой ссылки будут отражать все остальные ссылки, указывающие на тот же объект. 2-й пример, снова ЗНАЧЕНИЕ ссылки на объект передается в функцию, функция изменяет значение ссылки, чтобы указать на новый объект, старый объект остается неизменным. 3-й пример, ссылка на значение ссылки на объект передается в функцию, таким образом, изменения в функции действуют на тот же объект.
s-hunter 28.04.2015 02:26:56
Прекрасные примеры и именно то, что я думал, произойдет. Я новичок в PHP (из фона Javascript / node.js), и иногда трудно понять, что происходит, но это очень ясно!
TKoL 13.05.2019 10:26:09
Этот пример излишне сложен. $yв этом нет необходимости - нет ничего, function changeValueчто требовало бы, чтобы оно было внутри class Y, чтобы объединить два не связанных между собой понятия. Я бы переместился function changeValueво внешнюю сферу, чуть выше $x = new X();. Удалить все ссылки на $y. Теперь легче увидеть, что первые два примера оставляют $ x в покое, а третий меняет свое содержимое на new Y(). Какой бы легче увидеть , если вы выбросили typeиз $x- за того , что , как Xи Yслучается, включают в себя $abcполе также не имеет отношения к тому , что показано
ToolmakerSteve 1.07.2019 23:22:05

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

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

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

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

60
28.10.2014 16:10:25
Я думаю, что это доказательство является неверным толкованием. Похоже, вы пытались обменяться ссылками. У вас проблема с назначением объектов. Вы переназначаете ссылку, которая является неизменной. Это значение, на которое оно указывает, может быть изменено изнутри. Переопределение свопа теперь проходит ** x, что позволяет изменить * x. Проблема в том, что мы думаем, что $ x = $ y изменит то, на что изначально указывает $ x.
grantwparks 17.06.2012 20:26:08
Это не доказательство . Результат первого примера - это именно то, что вы ожидаете, если текущее значение всего объекта будет передано swapфункции; другими словами, если объекты были «переданы по значению». С другой стороны, это также именно то, что вы ожидаете, если дескриптор объекта будет передан функции, что на самом деле и происходит. Ваш код не различает эти два случая.
EML 12.05.2015 21:58:53

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

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

30
3.08.2008 23:57:46

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

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

25
28.06.2017 13:18:06
«Объекты» не являются значениями в PHP5 и не могут быть «переданы». Значение $fooявляется указателем на объект . $fooбудет передаваться по значению функции changeFoo(), а changeFoo()не объявить его параметр с &.
newacct 1.10.2013 00:03:01

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

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

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

$result=5;
changeValue($result);

echo $result; // $result is 6 here
?>
8
21.12.2014 10:21:07

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

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

так

    $fred = 5;
    $larry = & $fred;
    $larry = 8;
    echo $fred;//this will output 8, as larry and fred are now the same reference.
6
22.02.2009 09:17:14
Это устарело и
fijiaaron 25.02.2010 18:32:18

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

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

5
4.08.2008 00:05:05
Все переменные передаются по значению в PHP, если параметр функции не имеет &.
newacct 1.10.2013 00:03:33

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

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

1
9.01.2010 16:34:13
«Объекты» не являются значениями в PHP5 и не могут быть «переданы». Все переменные передаются по значению, если параметр передаваемой функции не имеет &.
newacct 1.10.2013 00:04:06
@newacct не совсем? Объекты несколько передаются по ссылке . Я думаю, что я заметил, что объекты php могут быть изменены функциями, даже если они не определены &перед параметрами в определении - если они были переданы по значению, объект, содержащийся в области видимости, вызвавший функцию с этим параметром, не быть затронутым.
Félix Gagnon-Grenier 21.12.2014 10:24:27
@ FélixGagnon-Grenier: опять же, «объекты» не являются значениями и не могут быть «переданы». Вы не можете иметь «переменную» в PHP5, значение которой является «объектом», вы можете иметь только значение, которое является ссылкой на объект (т. Е. Указатель на объект). Конечно, вы можете передать или назначить указатель на объект по значению и изменить объект, на который он указывает, вызвав метод, который выполняет такое изменение. Это не имеет ничего общего с передачей по ссылке. Тип значения и то, является ли параметр передачей по значению / передачей по ссылке, являются независимыми и ортогональными вещами.
newacct 21.12.2014 10:28:35
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
11.05.2010 15:51:24

Для тех, кто сталкивается с этим в будущем, я хочу поделиться этим драгоценным камнем из документов PHP, опубликованных анонимным пользователем :

Кажется, здесь есть некоторая путаница. Различие между указателями и ссылками не особенно полезно. Поведение в некоторых уже опубликованных «всеобъемлющих» примерах можно объяснить более простыми объединяющими терминами. Например, код Хейли делает именно то, что и следовало ожидать. (Используя> = 5.3)

Первый принцип: указатель хранит адрес памяти для доступа к объекту. Каждый раз, когда объект назначается, создается указатель. (Я еще не углубился в движок Zend, но, насколько я понимаю, это применимо)

2-й принцип и источник наибольшей путаницы: передача переменной в функцию выполняется по умолчанию как передача значения, т. Е. Вы работаете с копией. «Но объекты передаются по ссылке!» Распространенное заблуждение как здесь, так и в мире 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.
}

?>

Я написал обширный, подробный пост в блоге на эту тему для JavaScript , но я считаю, что он одинаково хорошо применим к PHP, C ++ и любому другому языку, где люди, похоже, не понимают , что такое передача по сравнению с передачей по ссылке.

Очевидно, что PHP, как и C ++, является языком, который поддерживает передачу по ссылке. По умолчанию объекты передаются по значению. При работе с переменными, которые хранят объекты, это помогает видеть эти переменные как указатели (потому что это на самом деле то, чем они являются на уровне сборки). Если вы передаете указатель по значению, вы все равно можете «отследить» указатель и изменить свойства объекта, на который указывает указатель. То, что вы не можете сделать, это указать на другой объект. Только если вы явно объявите параметр как переданный по ссылке, вы сможете сделать это.

1
20.04.2020 17:14:01

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

0
15.07.2015 11:25:18

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

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
0
31.03.2018 12:34:37

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

-7
3.08.2008 22:52:11
Я не думаю, что это правда.
Nick Heiner 17.08.2009 23:44:20