Вопрос

Текущая ситуация:

  • у меня есть текущая версия моей MVC Framework, которая использует классы в качестве контроллеров.
  • У меня есть несколько «винтажных» модулей из моего старый MVC Framework, который использует простые, плоские включения в качестве контроллеров.

Очень упрощенно это означает:

Новая версия:

<?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"или что-то подобное?

(Одним из решений моей проблемы было бы изменить мои старые контроллеры, чтобы они начинались с набора «глобальных» команд, но я бы предпочел решение, при котором мне не придется менять так много старого кода.)

(Примечание:Пожалуйста, не говорите мне, что ГЛОБАЛЫ — это плохо.Это совершенно не соответствует сути этого вопроса.Просто примите тот факт, что необходимо, чтобы старый код работал в новой, более чистой среде.)

Это было полезно?

Решение

Вы можете добавить локальные переменные, определенные в 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');
    }
}

Обратите внимание, что для того, чтобы это работало как положено, вам следует вызвать require перед использованием любого другого элемента функции.get_define_vars() возвращает только переменные из текущей области, поэтому никаких хаков array_diff не требуется.

Другие советы

Это самое простое решение, которое я могу придумать.

Дважды используйте функцию get_define_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?

Реестр — это контейнер для хранения объектов и значений в пространстве приложения.Сохраняя значение в реестре, один и тот же объект всегда доступен во всем приложении.Этот механизм является альтернативой использованию глобального хранилища.

http://framework.zend.com/manual/en/zend.registry.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top