Использование ссылки на несуществующее значение устанавливает переменную в NULL? - PullRequest
3 голосов
/ 07 декабря 2010

При передаче несуществующего значения по ссылке PHP создает значение и устанавливает его в NULL. Я заметил это, когда происходило увеличение памяти при проверке пустых значений в некоторых функциях. Возьмите следующую функцию:

function v(&$v,$d=NULL){return isset($v)?$v:$d;}
$bar = v($foo, $default);

Это было бы сокращение для:

if(isset($foo))
{
    $bar = $foo;
}
else
{
    $bar = $default;
}

Однако при передаче несуществующих переменных PHP создает их. В случае переменных - они удаляются, как только метод / функция завершается, - но для проверки суперглобальных массивов, таких как $ _GET или $ _POST, элемент массива никогда не удаляется, что вызывает дополнительное использование памяти.

$request_with = v($_SERVER['HTTP_X_REQUESTED_WITH']);

Может кто-нибудь объяснить, почему это происходит и является ли это исправлением todo на PHP или возможностью какого-то другого сумасшедшего использования значений?

Ответы [ 2 ]

3 голосов
/ 07 апреля 2015

Функция XeonCross 'v является сокращением для часто используемых:

$val= isset($arr['elm']) ? $arr['elm'] : 'default'

, чтобы избежать страшного уведомления «Неопределенный индекс: вяз».Хорошая вспомогательная функция будет выглядеть так:

function ifset(&$v1, $v2 = null) {
    return isset($v1) ? $v1 : $v2;
}

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

$val = ifset($arr['elm'],'default') 

, однако в этом есть много интересных (?) Уловоклюбимый «язык», который мы называем PHP:

внутри функции ifset, $ v1 кажется UNSET, поэтому он правильно возвращает значение $ v2, и вы можете заключить, что ifset работает нормально.Но после этого $ arr ['elm'] автоматически устанавливается в NULL.Итак, рассмотрим следующее:

    function wtf(&$v) {
       if (isset($v))
           echo "It is set";
       else
           echo "It is NOT set";
    }
    $p=[];
    wtf($p['notexist']);   => It is NOT set
    $p;                    => [ 'notexist' => NULL ]

Но это еще одно заблуждение, поскольку функция isset () возвращает false и для значений NULL:

$x=NULL;
isset($x)   => false... huh??

Мы ожидали этого?ну .. это есть в документации, так что это тоже по замыслу.Добро пожаловать в чудесный мир php.

3 голосов
/ 07 декабря 2010

Причина утечки памяти в том, что вы говорите об этом.

Когда вы запрашиваете ссылочный параметр, PHP предоставит вам его. Когда вы вызываете функцию с неустановленной переменной, PHP установит переменную и затем передаст ссылку на эту новую переменную. Когда вы называете это с суперглобальным, это создает отсутствующий индекс. Это потому что ты сказал это.

Однако я должен спросить, почему конкретно вам нужны ссылки на переменные? В 99,9% случаев они вам действительно не нужны. Я подозреваю, что это будет нормально работать:

function v($v, $d = null) { return isset($v) ? $v : $d; }

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

function &v(&$v, $d = null) { 
    if (isset($v)) {
        return $v;
    }
    return $d;
}

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

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