<rmcreative>

RSS

unset

5 сентября 2011

Ещё одна интересная особенность PHP, которую хорошо бы знать, чтобы не терять много времени при встрече с ссылочным foreach:

$val = '2';
$arr = array('1', &$val);
var_dump($arr);
unset($val);
var_dump($arr);

Штука действительно очень зла, если про неё забыть. Максим напоминал мне больше, чем целый день…

Комментарии RSS

  1. №5312
    Алексей
    Алексей 05 сент. 2011 г., 23:10:32

    Интересно, а какое поведение ожидалось?

  2. №5313
    kipelovets
    kipelovets 05 сент. 2011 г., 23:39:39

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

    <?php
     
    $val = '3';
    $arr = array('2', &$val);
    var_dump($arr);
    $val = '4';
    var_dump($arr);
    unset($val);
    var_dump($arr);
  3. №5314
    Spider
    Spider 05 сент. 2011 г., 23:58:35

    Если вдуматься, то тут, в принципе, всё логично. Мы имеем две ссылки на одно значение, потом одну убрали (unset), вторая осталась

  4. №5315
    Spider
    Spider 06 сент. 2011 г., 0:00:19
    $a = 1;
    $b = &$a;
    unset($a);
    echo $b; // 1
  5. №5316
    Sam
    Sam 06 сент. 2011 г., 0:04:19

    kipelovets, если проект — база для тысяч приложений и хочется нечто сделать максимально быстро и эффективно, может и встретиться.

    Вообще, конечно, поведение логично, если не забывать про то, как на самом деле работают ссылки.

  6. №5317
    Максим
    Максим 06 сент. 2011 г., 0:43:53

    Ох и намучался я объяснять ) Но момент и вправду очень тонкий. Сэм если захочет даст реальный пример где я его выловил.

  7. №5318
    MoLe-X
    MoLe-X 06 сент. 2011 г., 14:59:36

    Было бы неплохо увидеть в живую

  8. №5320
    Sam
    Sam 06 сент. 2011 г., 21:45:21

    Это был баг в Yii. После фикса, правда, подумали ещё и убили источник проблемы.

  9. №5322
    Psih
    Psih 07 сент. 2011 г., 13:53:49

    Ну убивать источник проблемы может было немного излишне, но с & + foreach нужно просто вдолбить себе в голову как аксиому - переменную по ссылке после цикла нужно уничтожить через unset. Иногда этот синтаксис очень неплохо вписывается. Тут как с любым продвинутым инструментом - удобно, круто и можно отрезать себе ногу при неправильном обращении :)

  10. №5323
    Spider
    Spider 07 сент. 2011 г., 13:55:17

    Да, я тоже как-то раз столкнулся с этим foreach со ссылками. Там тоже было интересно. Было 2 цикла foreach подряд (что-то вроде foreach ($array1 as &$element)... а после него foreach ($array2 as &$element)). Попробуйте — будет весело :)

  11. №5324
    Psih
    Psih 07 сент. 2011 г., 14:13:15

    Spider Да я тоже один раз такую ошибку допустил, минут 5 пытался понять что не так, потом дошло что ссылки виноваты. С тех пор всегда делаю unset сразу ещё до написания тела цикла

  12. №5331
    ostin
    ostin 12 сент. 2011 г., 18:09:59

    Да, проблема может легко добавить головной боли в крупном проекте. Но хорошо написанный тест спасет в этой ситуации ;)

    Про баг в yii: написал в code-review на гугле, но продублирую и здесь. Далее по коду используется isset() на изменяемые элементы массива. После изменения unset не производится и проверка может отработать не так, как ожидается.

  13. №5336
    Sam
    Sam 13 сент. 2011 г., 22:35:28

    ostin, там же уже отписались ;)

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.