简体   繁体   English

如何实现“require_global”?

[英]How to achieve “require_global”?

Current situation:现在的情况:

  • I have the current version of my MVC Framework which uses classes as controllers.我有我的 MVC 框架的当前版本,它使用类作为控制器。
  • I have some "vintage" modules from my old MVC Framework which uses simple, flat includes as controllers.我有一些来自MVC 框架的“老式”模块,它们使用简单、扁平的包含作为控制器。

Much simplified that means:大大简化,这意味着:

New Version:新版本:

<?PHP
class blaController extends baseController {
    private $intVar;

    function dosomethingFunction() {
        $this->intVar = 123;
        $this->view('myView');
    }
}
?>

Old Version:旧版:

<?PHP
$globalVar = 123;
// view "controllername" is automatically shown
?>

I'm now trying to write a wrapper to be able to use my old controllers in my new MVC without having to rewrite everything.我现在正在尝试编写一个包装器,以便能够在我的新 MVC 中使用我的旧控制器而无需重写所有内容。 To do so, I have a "wrapper" controller:为此,我有一个“包装器”控制器:

class wrapController extends baseController {
    function dosomethingFunction() {
        require 'old_dosomething.function.php';
        $this->view('old_dosomething_view');
    }
}

(Once again: This is VERY, VERY simplified - just to get the idea over. Not actual code.) (再一次:这是非常非常简化的 - 只是为了让想法结束。不是实际的代码。)

The problem with that approach is, that the previously global variable $globalVar now only exists inside of the method "dosomethingFunction" and cannot be accessed by the view.这种方法的问题是,以前的全局变量 $globalVar 现在只存在于方法“dosomethingFunction”内部,不能被视图访问。

This wouldn't be the case if I could force the require to behave as "in global scope" so that $globalVar would once again be available in global scope.如果我可以强制 require 表现为“在全局范围内”,这样 $globalVar 将再次在全局范围内可用,情况就不会如此。

So: Is there some way to achieve " require_global " or something similar?那么:有没有办法实现“ require_global ”或类似的东西?

(One solution for my problem would be to modify my old controllers to start with a bunch of "global" commands, but I'd prefer a solution where I don't have to change so much of that old code.) (我的问题的一个解决方案是修改我的旧控制器以从一堆“全局”命令开始,但我更喜欢一个不需要更改这么多旧代码的解决方案。)

(Note: Please don't tell me that GLOBALS are bad. It totally misses the point of this question. Just accept that it is a requirement to keep some old code working in a newer, cleaner environment.) (注意:请不要告诉我 GLOBALS 是坏的。它完全没有抓住这个问题的重点。只是接受让一些旧代码在更新、更清洁的环境中工作是一项要求。)

You can add local variables defined within dosomethingFunction() to global scope:您可以将在 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');
    }
}

Note, that for this to work as expected, you should call require before using any other thing in the function.请注意,要使其按预期工作,您应该在使用函数中的任何其他内容之前调用 require。 get_defined_vars() returns only variables from the current scope, so no array_diff hacks are needed. get_defined_vars() 仅返回当前作用域中的变量,因此不需要 array_diff 技巧。

This is the easiest solution I can think of.这是我能想到的最简单的解决方案。

Use the get_defined_vars() function twice and get a diff of each call to determine what variables were introduced by the required file.使用 get_defined_vars() 函数两次并获取每次调用的差异,以确定所需文件引入了哪些变量。

Example:例子:

$__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');

Hmmm, this is an issue I've never before seen.嗯,这是我以前从未见过的问题。 I suppose you could do this我想你可以这样做

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');
    }
}

But that's a pretty tedious, manual process as well, depending on how many globals we're talking about.但这也是一个相当乏味的手动过程,这取决于我们谈论的全局变量的数量。 I'll think about this, but I don't know of any "auto-magic" solution off the top of my head.我会考虑这个,但我不知道有什么“自动魔法”解决方案。

For anybody interested: My (so far) final version:对于任何感兴趣的人:我的(到目前为止)最终版本:

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');
    }
}

Ugly, but it works.丑陋,但它的工作原理。 Thanks for all your great help!感谢您的大力帮助!

Have you tried Zend_Registry from Zend Framework?您是否尝试过 Zend Framework 中的 Zend_Registry?

The registry is a container for storing objects and values in the application space.注册表是一个容器,用于在应用程序空间中存储对象和值。 By storing the value in the registry, the same object is always available throughout your application.通过将值存储在注册表中,相同的对象在整个应用程序中始终可用。 This mechanism is an alternative to using global storage.此机制是使用全局存储的替代方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM