代码之家  ›  专栏  ›  技术社区  ›  Marcelo Cantos

PHP:“全局”包括

  •  4
  • Marcelo Cantos  · 技术社区  · 15 年前

    当前情况:

    • 我有 当前版本
    • 我有一些“老式”模块从我的 古老的

    新版本:

    <?PHP
    class blaController extends baseController {
        private $intVar;
    
        function dosomethingFunction() {
            $this->intVar = 123;
            $this->view('myView');
        }
    }
    ?>
    

    旧版本:

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

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

    (再一次:这是非常非常简单的-只是为了让想法结束。不是实际的代码。)

    这种方法的问题是,以前的全局变量$globalVar现在只存在于方法“dosomethingFunction”中,视图无法访问它。

    如果我可以强制require以“在全局范围内”的方式运行,这样$globalVar将再次在全局范围内可用,那么情况就不会是这样了。

    那么:有什么方法可以实现?” 需要全球 “还是类似的?

    (我的问题的一个解决方案是修改我的旧控制器,从一堆“全局”命令开始,但我更喜欢一个不需要更改太多旧代码的解决方案。)

    (注意:请不要告诉我GLOBALS是不好的。它完全没有抓住这个问题的重点。只要接受这一点,就可以让一些旧代码在更新、更干净的环境中工作。)

    5 回复  |  直到 4 年前
        1
  •  6
  •   vartec    15 年前

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

        2
  •  4
  •   Matt    15 年前

    使用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');
    
        3
  •  1
  •   Peter Bailey    15 年前

    嗯,这是我从未见过的问题。我想你能做到

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

    但这也是一个相当乏味的手动过程,这取决于我们讨论的全局数。我会考虑一下,但我不知道有什么“自动魔法”的解决方案。

        4
  •  1
  •   Marcelo Cantos    15 年前

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

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

    很难看,但很管用。谢谢你的大力帮助!

        5
  •  0
  •   uuɐɯǝʃǝs uuɐɯǝʃǝs    15 年前

    您是否尝试过Zend Framework中的Zend_注册表?

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