2009-04-15 5 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を再度使用できるようにすることはできません。

So:「require_global」などの何らかの方法がありますか?

(私の問題の解決策の1つは、古いコントローラを "グローバル"コマンドの束から始めるように変更することですが、古いコードをあまり変更する必要がないソリューションを好むでしょう。 )

(注: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ハックは必要ありません。

+0

私はまだわからないが、何らかの理由でarray_mergeが私のシナリオで動作しないのは、foreachで "手動で"配列をマージするときです。 – BlaM

+0

まあ、$ GLOBALは本当に "普通の"配列ではありません。 foreachバージョンにロールバックされます。 – vartec

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

4

これは私が考えることができる最も簡単な解決策です。

get_defined_vars()関数を2回使用し、各呼び出しのdiffを取得して、必要なファイルによってどの変数が導入されたかを判断します。

例:

$__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

+0

良い点。誰かが後でその関数に変数を追加することは確かに可能です。 – Matt

+0

変数の1つが文字列に変換できないオブジェクトの場合、array_diff_assocは失敗します。 – BlaM

0

あなたはZend Frameworkのから除き、Zend_Registryを試してみましたか?

レジストリは、アプリケーション空間にオブジェクトと値を格納するためのコンテナです。レジストリに値を格納することにより、アプリケーション全体で同じオブジェクトを常に使用できます。このメカニズムは、グローバルストレージを使用する代わりに使用できます。

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

+0

それは私が避けようとしている古いコードを変更する必要があります。 – BlaM

+0

...私はZend_Registryが単純なグローバル配列よりも優れているのを見ていません... – BlaM

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

醜いが、それは動作します。あなたの大きな助けに感謝します!

関連する問題