2009-04-15 80 views
4

現狀:PHP:「全球」包括

  • 我有我的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」方法內部,不能被視圖訪問。

如果我可以強制require作爲「全局作用域」中的行爲,那麼$ globalVar將再次在全局範圍內可用,情況並非如此。

所以:有沒有辦法實現「require_global」或類似的東西? (我的問題的一個解決方案是修改我的舊控制器以一堆「全局」命令開始,但我更喜歡一個解決方案,我不必更改那麼多舊代碼。 )

(請注意:請不要告訴我GLOBALS是不好的,它完全沒有提到這個問題,只是認爲這是保持一些舊代碼在更新,更清潔的環境中工作的必要條件。)

回答

5

您可以添加()內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()僅從當前作用域返回變量,因此不需要使用array_diff hack。

+0

我還不確定爲什麼,但以某種方式array_merge不工作在我的方案,而手動合併數組與foreach作品。 – BlaM 2009-04-15 15:15:20

+0

好吧,$ GLOBAL並不是真正的「正常」數組。回滾到每個版本。 – vartec 2009-04-15 15:22:03

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

但是,這是一個相當繁瑣的,手工工藝爲好,這取決於我們有多少全局議論紛紛。我會考慮這一點,但我不知道任何「自動魔法」解決方案。

+0

」$ GLOBALS ['globalVar'] = $ globalVar;「如果我可以遍歷所有局部變量,將會是一個選項,但有沒有一種「自動化」的方式來找到所有這些? – BlaM 2009-04-15 14:42:33

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'); 
+0

如果你從一個函數內調用它,不需要做array_diff。 get_defined_vars()只返回當前範圍內的變量。 – vartec 2009-04-15 14:59:46

0

你從Zend框架試圖合適的詞彙?

註冊表是用於在應用程序空間中存儲對象和值的容器。通過將值存儲在註冊表中,整個應用程序始終可以使用相同的對象。該機制是使用全局存儲的替代方法。

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

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

醜陋,但它的作品。感謝您的所有幫助! 「