2

から変数をView渡すように非常に単純なクラスを適応させたので、変数を直接呼び出すことができます。ControllerViewView

<?php echo $name; ?>

そしてそうではない

<?php echo $this->name; ?>

すべてのビュー vars は vars eg$vars['name'] = "test"と呼ばれる連想配列に格納され、 __setvars を割り当てる機能が設定されています。

$v = new View;
$v->name="test";
$v->out(); 

したがってout()、変数を渡し、追加したビュー HTML を含む関数で:

    foreach($this->vars as $key=>$val) {
      $$key=$val;
    }
include $this->view_file;

$this次に、テンプレートで使用するとどうなるかをテストし、次のような対応する変数を追加しました

$v->this = "test_this";

私の仮定は、$this再割り当てできないためにコードが失敗するか、再割り当てされたとしても-ここを参照-再割り当てされたためにコードが失敗するということでし$thisた。

include $this->view_file;

うまくいきません!

代わりに、それは機能しました。 、またはequals$thisを使用して直接呼び出された場合でも、元の値を指しています!!echo $this;var_dump($this);"test_this"$this->view_file

どうすればいいの?

その後、使用を再テストしましextract($this->vars, EXTR_OVERWRITE)$thisが、触れられませんでした!

一般に、変数をビューに渡し、関数での衝突を回避するための正しいアプローチは何でしょうか

function out($view, $toString = false)
{
    extract($this->vars);
    include $view;
}

vars には、view または "this" と呼ばれる var が含まれているか、テンプレートがその$viewvar を使用する可能性があります。

  1. 心配する必要はありません。view という変数を割り当てないようにしてください。
  2. out()のように、関数内で長い変数名を使用します$longVarNameSoThatThereWillNotBeCollisions
  3. 関数に必要なすべての vars を$this->temp:に割り当てます。$this->temp['view']次に、unset($view)- そして、- と$this呼ばれる変数を正気で使用する人$thisView!
4

2 に答える 2

4

再割り当ての保護を回避できたにもかかわらず、オブジェクトのプロパティにアクセスできる理由を説明するには$this、コンパイルされたスクリプト用に生成されたオペコードを調べる必要があります。

オブジェクトのプロパティには、FETCH_OBJ_Rオペコードを使用してアクセスします。

のようなコードを書くと

$myObject = new testClass;
$myObject->property

コンパイルされたコードは、2 つのパラメーターで生成さFETCH_OBJ_Rます。1 つ目はオブジェクトを含む変数で、2 つ目はプロパティの名前です。

Vulcan 逆アセンブラーを使用すると、出力は次のようになります。

FETCH_OBJ_R                                      $1      !1, 'property'

$1戻り値が格納される場所であり!1、オブジェクトを含む変数です。

ただし、生成された出力を使用してプロパティにアクセスする場合$thisは、少し異なります。

FETCH_OBJ_R                                      $1      'property'

1 つのパラメーターを持つオペコードは、プロパティ ルックアップを、それが呼び出されたオブジェクトに解決します。

あなたの質問への答えは$this->property、コンパイル時に解決されました。壊したとはいえ$this、 の場所はpropertyすでに決まっていた。

于 2012-07-10T15:29:37.070 に答える
0

これは私に少し興味があり、あなたが正しいようです$this

あなたが正しく言ったように:

<?php
$var = 'this';
$$var = 'hello';

echo $this;

動作しますが、

<?php
$this = 'hello';

echo $this;

しません。

おそらくbugs.php.netに報告して、これに対する公式の回答があるかどうかを確認してください。

$thisの実際の価値がまったく異なるものであるにもかかわらず、既存のメンバーがまだ機能しているという事実は、$this絶対に起こってはならず、何らかの形の核心的な問題でなければなりません. 私が考えることができる唯一のことは、どういうわけか$this、実際の「実際の」変数ではなく、魔法のコンテキスト変数として使用されていることです (もちろん驚くべきことではありませんが、それは PHP です!)。variable-variable からの代入のバグ (これは明らかに起こるべきではありませ$thisん!) により、偽の変数であるという事実が開発者に表示される可能性があります。

魔法テスト:

<?php

class ThisTest {
    public function SetAndUseThis() {
        $var = 'this';
        $$var = 'that';
        var_dump($this);
        var_dump($this->variable);
        var_dump($this->AnotherMethod());
    }

    public $variable = 'i am a variable';

    public function AnotherMethod()
    {
        return 9.0;
    }
}

$inst = new ThisTest();
$inst->SetAndUseThis();

結果:

string(4) "that" string(15) "i am a variable" float(9)
于 2012-07-10T14:55:44.457 に答える