1

次のコードに出くわしましたが、phpのgetおよびsetマジックメソッドを使用して、スクリプトの出力が直感的でないシーケンスで出力された理由を理解できませんでした。

class Magic
{
    public $a = "A";
    protected $b = array("a" => "A", "b" => "B", "c" => "C");
    protected $c = array(1,2,3);

    public function __get($v)
    {
        echo "$v";
        return $this->b[$v];
    }
    public function __set($var, $val)
    {
        echo "$var: $val";
        $this->$var = $val;
    }
}
$m = new Magic();
echo $m->a . "," . $m->b . "," . $m->c . ",";
$m->c = "CC";
echo $m->a . "," . $m->b . "," . $m->c;

出力は次のとおりです。

bcA,B,C,c
CCbcA,B,C

まず第一に、なぜAを出力しないのですか?出力の順序は意味がありません。

4

3 に答える 3

1

誰かが Zend 認定のために勉強しています ;-)

その理由は、魔法のメソッドは、プロパティにアクセスできない場合にのみトリガーされるためです。

そのため、最初のエコーで$m->aは、これがアクセス可能なプロパティであることをフェッチするため、エコーされず、__get単に返されます。この後、 と の両方$b$cアクセスできないため、エコーされてから返されます。

したがって、最初のエコーからの出力は次のとおりです。

b // echo'd by __get
c // echo'd by __get
A // simply returned, and echo'd in the concatenated string
B // (As above)
C // (As above)
于 2013-02-19T13:37:00.840 に答える
1

理由は非常に簡単です。文字列の連結を行うため、PHP は文字列を出力する前に完全な文字列を準備する必要があります。これは、連結する必要があるすべてを実行することを意味します。実行するとgetter__getメソッドはアクセスできないメンバーに対してのみ呼び出されます)、echo最初に実行されてから値が返されます。

それらを個別にエコーアウトすると、すべてがその場所にあります。

于 2013-02-19T13:37:26.393 に答える
0
echo $m->a . "," . $m->b . "," . $m->c . ",";

この行が呼び出されると、連結が行われる前にまず変数名が解決されます。

したがって、$m->a、$m->b、$m->c の順に検索します。

$m->a は公開プロパティ a に解決されるため、あなたの をトリガー_getしないため、そこにあるエコーはすぐには送信されません。ただし、$m->bそれをトリガーするため、エコーが発生します。

最後に、変数が解決されると、連結された文字列全体が出力されます。

于 2013-02-19T13:38:29.003 に答える