Текущая ситуация:
Это значительно упростило это:
Новая версия:
<?PHP class blaController extends baseController { private $intVar; function dosomethingFunction() { $this->intVar = 123; $this->view('myView'); } } ?>
Старая версия:
<?PHP $globalVar = 123; // view "controllername" is automatically shown ?>
Теперь я пытаюсь написать оболочку, чтобы иметь возможность использовать мои старые контроллеры в моем новом MVC, не переписывая все. Для этого у меня есть «оберточный» контроллер:
class wrapController extends baseController { function dosomethingFunction() { require 'old_dosomething.function.php'; $this->view('old_dosomething_view'); } }
(Еще раз: это ОЧЕНЬ, ОЧЕНЬ упрощено – просто для того, чтобы получить представление. Не настоящий код.)
Проблема с этим подходом заключается в том, что ранее глобальная переменная $ globalVar теперь существует только внутри метода «dosomethingFunction» и к ней не может быть доступа.
Это было бы не так, если бы я мог заставить требование вести себя как «в глобальном масштабе», так что $ globalVar снова будет доступен в глобальной области.
Итак: Есть ли способ достичь « require_global » или что-то подобное?
(Одним из решений для моей проблемы было бы изменить мои старые контроллеры, чтобы начать с кучи «глобальных» команд, но я бы предпочел решение, в котором мне не нужно менять такой старый код.)
(Примечание: Пожалуйста, не говорите мне, что GLOBALS – это плохо. Это полностью упускает суть этого вопроса. Просто примите, что это требование, чтобы какой-то старый код работал в более новой, более чистой среде.)
Вы можете добавить локальные переменные, определенные в dosomethingFunction (), в глобальную область:
class wrapController extends baseController { function dosomethingFunction() { require 'old_dosomething.function.php'; //begin added code $vararr = get_defined_vars(); foreach($vararr as $varName => $varValue) $GLOBALS[$varName] = $varValue; //end added code $this->view('old_dosomething_view'); } }
Обратите внимание, что для этого, как и следовало ожидать, вы должны вызвать запрос перед использованием любой другой функции. get_defined_vars () возвращает только переменные из текущей области, поэтому нет необходимости в массивах.
Это самое легкое решение, о котором я могу думать.
Используйте функцию get_defined_vars () дважды и получите разницу каждого вызова, чтобы определить, какие переменные были введены требуемым файлом.
Пример:
$__defined_vars = get_defined_vars(); require('old_dosomething.function.php'); $__newly_defined_vars = array_diff_assoc($__defined_vars, get_defined_vars()); $GLOBALS = array_merge($GLOBALS, $__newly_defined_vars); $this->view('old_dosomething_view');
Хммм, это проблема, которую я никогда раньше не видел. Я полагаю, вы могли бы это сделать
class wrapController extends baseController { function dosomethingFunction() { require 'old_dosomething.function.php'; // Force "old" globals into global scope $GLOBALS['globalVar'] = $globalVar; $this->view('old_dosomething_view'); } }
Но это довольно утомительный ручной процесс, в зависимости от того, сколько глобалов мы говорим. Я подумаю об этом, но я не знаю ни одного решения «автомагии» с моей головы.
Для всех, кого интересует: Моя (до сих пор) окончательная версия:
class wrapController extends baseController { function dosomethingFunction() { // ... do some initialisation stuff ... $__defined_vars = array_keys(get_defined_vars()); require 'old_dosomething.function.php'; $__newly_defined_vars = array_diff( array_keys(get_defined_vars()), $__defined_vars, array('__defined_vars') ); foreach ($__newly_defined_vars as $var) { $GLOBALS[$var] = &$$var; } $this->view('old_dosomething_view'); } }
Уродливо, но это работает. Спасибо за вашу большую помощь!
Вы пробовали Zend_Registry из Zend Framework?
Реестр представляет собой контейнер для хранения объектов и значений в прикладном пространстве. Сохраняя значение в реестре, тот же объект всегда доступен в вашем приложении. Этот механизм является альтернативой использованию глобального хранилища.