PHP:“全球”包括在内

时间:2009-04-15 14:30:17

标签: php include scope global

现状:

  • 我有MVC框架的当前版本,它使用类作为控制器。
  • 我的 MVC框架中有一些“复古”模块,它使用简单,扁平的包含作为控制器。

很简化意味着:

新版本:

<?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是坏的。它完全忽略了这个问题的要点。请接受这是一个要求让一些旧代码在更新,更清洁的环境中工作。)

5 个答案:

答案 0 :(得分:6)

您可以将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_defined_vars()只返回当前作用域中的变量,因此不需要array_diff hacks。

答案 1 :(得分:4)

这是我能想到的最简单的解决方案。

使用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');

答案 2 :(得分:1)

嗯,这是我以前从未见过的问题。我想你可以做到这一点

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

但这也是一个非常乏味的手动过程,取决于我们谈论的全局变量。我会想到这一点,但我不知道任何“自动魔术”解决方案。

答案 3 :(得分:1)

对于任何感兴趣的人:我的(到目前为止)最终版本:

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

丑陋,但它确实有效。感谢您的大力帮助!

答案 4 :(得分:0)

您是否尝试过Zend Framework的Zend_Registry?

注册表是用于在应用程序空间中存储对象和值的容器。通过将值存储在注册表中,整个应用程序中始终可以使用相同的对象。此机制是使用全局存储的替代方法。

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