-1

私は今、可能な限りシンプルにするアプリを書いています。私のコントローラーは、次のことを行う render($Layout)メソッドを実装しています。

public function render($Layout) {
  $this->Layout = $Layout;
  include( ... .php)
}

次の問題がよくわかりません。コントローラーで変数を定義します。

public function somethingAction() {
  $someVariable = "something";
  $this->render('someLayout');
}

PHPビューファイル(レンダリング関数に含めたものと同じ)で、変数をエコーし​​ようとしましたが、何もありません。ただし、次のようにアクション メソッドを宣言すると:

public function somethingAction() {
  global $someVariable;
  $someVariable = "something";
  $this->render('someLayout');
}

そして私の見解では、次のように:

global $someVariable;
echo $someVariable;

それは機能します。それでも毎回グローバルという言葉を書くのは面倒です。

これどうやってするの?$_GLOBAL 配列は使用したくありません。たとえば、Cake PHP では、$this->set('varName', $value) のようなメソッドがあります。次に、ビュー内の変数に$varNameとしてアクセスできます。それはどのように行われますか?

4

2 に答える 2

3

PHPマニュアルからinclude

ファイルがインクルードされると、そこに含まれるコードは、インクルードが発生した行の変数スコープを継承します。呼び出しファイルのその行で使用可能な変数は、その時点以降、呼び出されたファイル内で使用できます。ただし、インクルード ファイルで定義されているすべての関数とクラスには、グローバル スコープがあります。

あなたがするとき

public function somethingAction() {
  $someVariable = "something";
  $this->render('someLayout');
}

$someVariable変数はスコープに限定されますsomethingAction()。メソッドには独自の変数スコープがあるため、メソッドを呼び出してrender()も魔法のように変数が で使用可能になるわけではありません。可能な解決策は、render()render()

public function somethingAction() {
  $this->render(
      'someLayout', 
      array(
          'someVariable' => 'something'
      )
    );
}

そして次に変更render()します

public function render($Layout, array $viewData) {
    $this->Layout = $Layout;
    include( ... .php)
}

$viewDataインクルードされたファイルが次のようになっている場合など、他の関数やメソッドで使用しようとしていない場合は、インクルードされたファイルにアクセスできます。

<h1><?php echo $viewData['someVariable']; ?></h1>

動作しますが、次のようになっている場合:

function foo() {  
    return $viewData['someVariable']; 
}
echo foo();

foo()独自の変数スコープがあるため、機能しません。

ただしコントローラーの唯一の責任は、入力を処理することです。レンダリングはビューの責任です。render()したがって、コントローラーにはメソッドがまったくないはずです。メソッドをViewクラスに移動することを検討してから実行してください

public function somethingAction() {
  $view = new View('someLayout');
  $view->setData('someVariable', 'something');
  $view->render();
}

View オブジェクトのrender()メソッドは、次のように実装できます。

class View
…
    $private $viewData = array();       

    public function setData($key, $value) 
    {
        $this->viewData[$key] = $data;
    }

    public function render()
    {
        extract($this->viewData, EXTR_SKIP);
        include sprintf('/path/to/layouts/%s.php', $this->layout);
    }

このextract関数は、キーを名前として使用して、現在のスコープ内の配列の値をインポートします。これにより、 の代わりにviewDataasでデータを使用できるようになります。ただし、使用する前に、セキュリティへの影響を理解していることを確認してください。$someVariable$this->viewData['someVariable']extract

これは、現在のやり方の代替案の 1 つにすぎないことに注意してください。ビューをコントローラーから完全に移動することもできます。

于 2013-03-03T10:59:33.410 に答える
0

使用すると、暗黙的に配列が使用globalされます。$_GLOBALS

グローバルは決して良いことではないため、推奨されない例:

function something() {
  global $var;
  $var = 'data';
}

// now these lines are the same result:
echo $_GLOBALS['var'];
global $var; echo $var;

単純に $this->set 関数を使用しないのはなぜですか?

public function render($Layout) {
  $this->Layout = $Layout;
  include( ... .php)
}

public function somethingAction() {
  $this->set('someVariable', "something");
  $this->render('someLayout');
}

// in a framework's managed view:
echo $someVariable;

あなたのフレームワークを詳しく知らなくて申し訳ありませんが、それは完全に理にかなっています。

実際の方法:extract現在のシンボル テーブルに連想配列をロードするネイティブ関数があります。

array( 'var0' => 'val0', 'var1' => 'val1')

になる

echo $var0; // val0
echo $var1; // val1

それはおそらく「何が起こるか」です。

于 2013-03-03T10:54:37.337 に答える