2016-01-06 3 views
6

Я думал, что PHP = было простым присвоением значений. Например:Почему поведение PHP ведет себя так?

$x = 1; 
$a = $x; 
$b = $x; 
$a++; 
echo $a; 
echo $b; 

Производит 21 как ожидалось. Однако приведенный ниже код ведет себя иначе, чем я ожидал. Я был в основном пытается присвоить «же» значение многих переменных:

class X { 
    public $val = 0; 

    public function doSomething() { 
     $this->val = "hi"; 
    } 
} 

function someFunction() { 
    $template = array('non_object' => 0, 'object' => new X()); 
    $a = $template; 
    $b = $template; 

    //Do something 
    $a['object']->doSomething(); 

    var_dump($a); 
    var_dump($b); 
} 

Производит:

array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#1 (1) { 
    ["val"]=> 
    string(2) "hi" 
    } 
} 
array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#1 (1) { 
    ["val"]=> 
    string(2) "hi" 
    } 
} 

Как вы можете увидеть object недвижимость в array A изменилась, как и ожидалось, но и изменили в array B.

Вы можете проверить код здесь: http://sandbox.onlinephpfunctions.com/code/bff611fc9854b777114d38a3b4c60d524fdf2e19

Как я могу присвоить такое же значение для многих PHP переменных и манипулировать ими, не имея их в этом состоянии «квантовая запутанность» и без копирования?

ответ

1

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

Получить код ниже

$a = $template; 
    $b = $template; 

Причина, почему вы получили неожиданный результат:

Что именно здесь происходит, $a и $b просто как «указатели» или указательных «обработчики» для того же объекта $template и то причина вы встретили что-то неожиданный потому что ты изменил объект через одну из ссылок $a и поскольку $b также ссылается на тот же объект, вы заметили изменения

от PHP Manual Objects and References

Одним из ключевых моментов ООП PHP5, который часто упоминается, является то, что объекты «по умолчанию передаются по ссылкам».Это не полностью true. В этом разделе вы можете исправить эту общую мысль, используя некоторые примеры.

Ссылка на PHP является псевдонимом, который позволяет двум различным переменным присваивать одно и то же значение. Начиная с PHP5, объектная переменная не содержит объект как значение больше. Он содержит только идентификатор объекта , который позволяет объектам доступа найти фактический объект. Когда объект отправляется аргументом, возвращенным или назначенным другой переменной , разные переменные не являются псевдонимами: они содержат копию идентификатор, который указывает на тот же объект.

5

Вы назначили переменные $ a и $ b с одним и тем же объектом. Так что если вы позвоните $a["object"]->doSomething() или $b["object"]->doSomething(), то получите тот же результат, потому что $a["object"] и $b["object"] такие же.

Если вам нужны выходы быть разными, попробуйте ниже код:

class X { 
    public $val = 0; 

    public function doSomething() { 
     $this->val = "hi"; 
    } 
} 

function someFunction() { 
    $a = array('non_object' => 0, 'object' => new X()); 
    $b = array('non_object' => 0, 'object' => new X()); 

    //Do something 
    $a['object']->doSomething(); 

    var_dump($a); 
    var_dump($b); 
} 

выход будет, как показано ниже:

array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#1 (1) { 
    ["val"]=> 
    string(2) "hi" 
    } 
} 
array(2) { 
    ["non_object"]=> 
    int(0) 
    ["object"]=> 
    object(X)#2 (1) { 
    ["val"]=> 
    int(0) 
    } 
} 

Здесь вы назначаете другой объект $ в $ б.

Please check this

+2

см. Также: http://docs.php.net/manual/en/language.oop5.references.php – VolkerK

1

Если вы хотите присвоить только значение, и можно использовать функцию: клон

class X { 
    public $val = 0; 

    public function increment() { 
    $this->val += 1; 
    } 
} 

function someFunction() { 
    $template =new X(); 
    $a = $template; 
    $b = clone $template; 

    //Increment a 
    $a->increment(); 

    var_dump($a); 
    var_dump($b); 
} 

someFunction(); 

$x = 1; 
$a = $x; 
$b = $x; 

$a++; 
echo $a; 
echo $b; 

check this

Смежные вопросы