Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Получение родительских областей видимости
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Приветствую.
Как известно, в PHP не существует понятия вложенных контекстов. То есть, находясь внутри функции, невозможно получить родительский контекст. Это приводит, например, к тому, что переменные контекста не видны в замыканиях, хотя это и исправляется при помощи ключевого слова use. И если с замыканиями всё более или менее очевидно, то получить родительский контекст, отличный от глобального, возможно только если имеется парадигма вложенных контекстов. Так как в PHP она отсутствует, то я написал реализацию этого механизма.
На деле, ничего хорошего такой подход не сулит - как правило, нет необходимости обращаться к родительским контекстам. Тем не менее, возможность работать внутри замыканий с контекстом родителя кажется естественной. Ниже привожу код класса, который может реализовать эту функциональность:
var_dump(Scope::getInstance()->getScope());//get parent scope vars
}
$rObj=new bar('objvar');
Существующие минусы данного решения:
0. Самый очевидный - это ужасный подход, поскольку приводит к исполнению родительского кода. Для небольших вычислений это допустимо, но если в родителе исполняется что-либо наподобие тяжёлых SQL-запросов или сетевых вычислений, то идея использовать Scope - не из разряда хороших.
1. На текущий момент нельзя обратиться к глобальному контексту через Scope. Недостаток, впрочем, не слишком значительный - так как есть $GLOBALS
2. На текущий момент я не придумал, как обращаться к переменным, которые являются значениями параметров по-умолчанию (они не объявляются в контексте родителя, не передаются при вызове родителя, но ссылаться на них в коде родителя корректно) - вот это существенный недостаток.
3. Невозможно использовать Scope из eval - просто потому, что я пока не придумал, как получить исполняемый код в eval() (тем не менее, сам признак того, что код исполняется в eval(), легко получить)
Интерес эта парадигма представляет скорее академический - я решал задачу, исходя из необходимости обращаться извне замыкания к контексту, не используя use или конструкции типа get_defined_vars - поскольку можно было модифицировать код внутри тела замыкания, но не код родителя.
Я не пробовал испытывать этот код на каких-нибудь нестандартных связках и сложном коде. Требуемая версия PHP - 5.4+
Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007 Откуда: Berlin
Помог: 707 раз(а)
Одно из применений уже сказано - получение полного контекста замыканием (вообще говоря, для замыкания классически свойственно иметь полный контекст - другое дело, что в PHP этого нет).
----- Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.