2008-08-03 2 views

ответ

207

Это по стоимости в соответствии с PHP Documentation.

По умолчанию аргументы функции передаются по значению (так что, если значение аргумента внутри функции изменяется, оно не изменяется вне функции). Чтобы позволить функции изменять свои аргументы, они должны передаваться по ссылке.

Чтобы иметь аргумент функции всегда передается по ссылке, добавьте амперсанд (&) перед именем аргумента в определении функции.

<?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.' 
?> 
+4

У меня также было это сомнение (новичок) - так, чтобы быть понятным, это было бы так же, как `$ str = add_some_extra ($ str);` если бы я не использовал ссылку, правильно? то какова реальная добавленная стоимость этого? – 2013-11-24 06:06:01

+3

@Obmerk Если вы не используете _not_, используя амперсанд для обозначения по ссылке, это не будет эквивалентно. Обратите внимание, как функция не имеет оператора return, поэтому `$ str` будет присвоен null в вашем случае. – 2015-01-22 19:31:39

+0

, если вы сделаете это так @ObmerkKronen, тогда вам придется вернуть значение и поймать его через свой код. Исходная переменная останется прежней. – 2016-04-04 20:54:31

-6

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

+8

Я не думаю, что это правда. – 2009-08-17 23:44:20

17

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

выведет:

FOO

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

+0

«Объекты» не являются значениями в PHP5 и не могут быть «переданы». Значение `$ foo` является указателем * на объект *. `$ foo` ** передается значением ** в функцию` changeFoo() `, так как` changeFoo() `не объявлял свой параметр с` & `. – newacct 2013-10-01 00:03:01

23

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

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

4

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

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

+0

Все переменные передаются по значению в PHP, если параметр функции не имеет `&`. – newacct 2013-10-01 00:03:33

51

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

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

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

для того, чтобы пройти по ссылке.

5

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

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

так

$fred = 5; 
    $larry = & $fred; 
    $larry = 8; 
    echo $fred;//this will output 8, as larry and fred are now the same reference. 
1
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: Б, SwapValues: а, б

36

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

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

7

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

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

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

$result=5; 
changeValue($result); 

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

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