2

この質問は関連しています: PHP マジック メソッドの例

承認された回答のコメントでこの質問をしましたが、気付いていないので、この質問を作成する必要があると思います。

<?php
    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;
?>

出力: b,c,A,B,C,c: CC,b,c,A,B,C

$m->c = "CC";ここでは、すでに同じ名前の保護された変数があります。では、これは可視性のコンテキストでどのように動作する必要がありますか?

保護された変数の値を上書きする場合、保護cされた/プライベート変数の抜け穴ではありませんか? (そんなことはないと思います)

そうでない場合、ステートメントは、$this->$var = $val;保護されていると既に定義されている同じ名前のパブリック変数を作成するようです。それは可能ですか?

また、このステートメントの後に:$m->c = "CC";に再度アクセス$m->cすると、PHP はパブリックな可視性がない__getかのように再度呼び出します。それは、すぐ次のステートメントの寿命がないcことを意味しますか? $this->$var = $val;(それも仕方ないとは思いますが)

誰でも説明できますか、そのような場合に動作する必要があり、どのようにそのような出力を出したのでしょうか?

4

2 に答える 2

2

cメソッドだけで変更されているようです。保護されている間、魔法のメソッドはそれを公開します。

この例を見ると:

class Magic
{
    protected $b = 'B';

    public function __get($v)
    {
        return 'C';
    }

    public function __set($v, $val)
    {
        $this->$v = $val;
    }
}

$magic->b = 'D';
echo $magic->b; // Outputs: C

最初の呼び出しではプロパティが に設定されますbD、ゲッターは を返すようにハードコードされているためCprotectedアクセス修飾子は引き続き尊重されます。

編集。

魔法のゲッター/セッターのもう 1 つの用途は、コレクションへのアクセスです。この例は、その柔軟性を示しています。

class Magic
{
    private $properties = array();

    public function __get($key)
    {
        if(isset($this->properties[$key])) {
            return $this->properties[$key];
        }
    }

    public function __set($key, $value)
    {
        $this->properties[$key] = $value;
    }

    public function dump($return = false)
    {
        if($return) {
            return print_r($this->properties, true);
        } else {
            print_r($this->properties);
        }
    }
}

$magic = new Magic();

$magic->a = '123';
$magic->b = '456';
$magic->c = '789';

echo '<pre>';

echo sprintf('A: %s%s', $magic->a, PHP_EOL);
echo sprintf('B: %s%s', $magic->b, PHP_EOL);
echo sprintf('C: %s%s', $magic->c, PHP_EOL);

echo PHP_EOL;

echo $magic->dump(true);

出力:

A: 123
B: 456
C: 789

Array
(
    [a] => 123
    [b] => 456
    [c] => 789
)

これらは単なる関数であるため、同じ規則に従います。唯一の違いは、それらが呼び出される方法です。

于 2014-01-21T09:08:26.757 に答える