Получение всех переменных из глобальной области видимости, превращаем локальную в глобальную область

Предположим у нас есть некая функция(как известно у функций своя локальная область видимости), в которой нам нужно использовать все переменные из глобальной области. Существует ключевое слово global после которого мы можем объявить эти переменные через запятую. Но это решение не подходит, в случае когда нам нужно получить и юзать все переменные из глобальной области в их обычном виде, но при этом мы даже не знаем всех их возможных имён. Их знает массив $GLOBALS возьмем из него всё что нужно и присвоим те же самые имена переменных:

foreach (array_filter(array_keys($GLOBALS), function ($key) {
    return $key != 'GLOBALS' && substr($key, 0, 1) != '_';
}) as $k) {
    ${$k} = &$GLOBALS[$k];
}

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

Т.е. по сути, мы превратили локальную область видимости в глобальную.

Зачем это нужно? Вот есть среда для веб разработки под php, хорошая штука рекомендую кстати. И там есть inpage шаблоны, которые встраиваются в страницы посредством вызова методов, которые по сути — это те же функции, с локальной областью видимости. А в методе у нас уже require отрабатывает внедряя нужный шаблон, после всех проверок прав доступов на него. И нам нужно внутри этого шаблона иметь все переменные объявленные в глобальной области, именно так, будто он «пришел сюда» не из функции, а так будто он был встроен обычной конструкцией require на странице, или кодом. Ведь там в глобальной области какие то пользовательские переменные могут быть, какие то подключения к бд и мало ли что ещё появится. К этому всему нужен доступ.

public static function inpage($id)
{
    foreach (array_filter(array_keys($GLOBALS), function ($key) {
        return $key != 'GLOBALS' && substr($key, 0, 1) != '_';
    }) as $k) {
        ${$k} = &$GLOBALS[$k];
    }
    $template = Templates::find($id);
    if ($user->access()->read($template)) {
        require $_SERVER['DOCUMENT_ROOT'] . $template->file;
    }
}

Красота. Вот вам фактически и динамический require со всеми переменными глобальной области, но только выполняемый функцией.

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *