Путаница с массивами PHP - PullRequest
3 голосов
/ 07 ноября 2010

С этим кодом:

$a[1]=1;
$a[2]=& $a[1];

$b=$a;
$b[2]=7;

print_r($a);

Я ожидал, что результат будет 1, потому что $a не назначен по ссылке на $b ($a = & $b), но получается 7.Почему?

Ответы [ 3 ]

4 голосов
/ 07 ноября 2010

Вы копируете массив по значению, но элементы исходного массива являются ссылками.Эти ссылки просто копируются в место назначения.

php > var_dump($a);
array(2) {
  [1]=>
  &int(1)
  [2]=>
  &int(1)
}
php > $b=$a;
php > var_dump($b);
array(2) {
  [1]=>
  &int(1)
  [2]=>
  &int(1)
}

Вот пример копирования массива по ссылке:

php > $c[1] = 1;
php > $c[2] =& $c[1];
php > var_dump($c);
array(2) {         
  [1]=>            
  &int(1)
  [2]=>
  &int(1)
}
php > $d =& $c;
php > var_dump($d);
array(2) {
  [1]=>
  &int(1)
  [2]=>
  &int(1)
}
php > $d = array(3,4,5);
php > var_dump($c);
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(4)
  [2]=>
  int(5)
}
php > var_dump($d);
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(4)
  [2]=>
  int(5)
}

Как видите, переменная массива (не элементы)сама по себе является ссылкой, поэтому изменение $d влияет на $c.Переназначение $b само по себе не влияет на $a.

3 голосов
/ 07 ноября 2010

Так работают ссылки. Когда вы делаете $a[2]=& $a[1];, вы говорите, что оба элемента $ a теперь содержат одну и ту же переменную. Когда вы делаете $ b = $ a, $ b и $ a - это разные переменные, но все 4 элемента внутри них указывают на одну и ту же переменную! Попробуйте сделать $b[3] = 7 и убедитесь, что он не скопирован в $ a - потому что $ b и $ a различны, а $ b [2] и $ a [2] - нет!

Ссылки немного грязные, извините. Избегайте их использования, если не обязаны.

0 голосов
/ 07 ноября 2010

Это помогает мне понять, что такое ссылки:

http://www.php.net/manual/en/features.gc.refcounting-basics.php

http://books.google.com/books?id=e7D-mITABmEC&pg=PT171&lpg=PT171&dq=php+object+zval&source=bl&ots=oawmzMtsXt&sig=mMSuVKsk6L3JWuEikJN8j7dQfRs&hl=ru&ei=JmDWTOraI4TNswaDt-jkCA&sa=X&oi=book_result&ct=result&resnum=10&ved=0CEcQ6AEwCQ#v=onepage&q=php%20object%20zval&f=false

И отладка с помощью xdebug интересных случаев тоже помогает

Например, вы можете «избегать» частных свойств:

class c{
    private $a = 42;
    function &a(){
        return $this->a;
    }
    function print_a(){
        echo $this->a;
    }
}
$c = new c;
$d = &$c->a();
echo $d;
$d = 2;
$c->print_a();

или передавать по ссылке на функции, если вы не объявили это:

function f1(&$s) {
    $s++;
}
function f2($s) {
    $s--;
}
$s1 = 1;
$s2 = 3;
f1($s1);
f2(&$s2);
echo $s1.$s2;

, также foreach может использовать передачу по ссылке

$ a = массив (1,2,3);foreach ($ a как $ key => & $ value) {$ value = 1;} $ value = 2;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...