3

プライベート変数の使用とアクセスに関するこの質問から、一般的な使用方法についての情報を入手したいと思います。オーバーロード関数を使用するのに最適な時期と場所、および使用した場所(ある場合)について疑問に思っています。__get()__set()

明確にするために、これらの関数について話します:http: //us2.php.net/manual/en/language.oop5.magic.php

4

4 に答える 4

3

レイジー モデルのゲッター (__get() を使用)

自分のアプリで PHP のマジック メソッドをあまり頻繁に使用した覚えはありませんが、ある状況で__get()非常に便利だったことは覚えています。

昔、私はCakePHPフレームワークでアプリケーションを開発していました.CakePHPフレームワークには多くのモデルがあり、特定のコントローラーで使用されるすべてのモデルは、メソッドがそれらのうちの1つまたは2つしか使用しない場合でも初期化されました(Cakeの動作方法です)。そこで、これを遅延モデルに変更することにしました (モデルが初めて使用されるときにモデルをロードします)。

私がしたことは__get()、特定の名前のモデルを探してロードする非常に単純な関数を追加したことだけです。3 ~ 4 行のコードでした。AppController (すべての CakePHP クラスはそのコントローラーから派生します) でそれを定義すると、突然、アプリの速度が上がり、メモリの使用量が減りました。

後でそれをさらに進めて、同じ方法で遅延コンポーネントの読み込みも行いました。

動的モデル メソッド (__call() を使用)

同じく CakePHP からのもう 1 つの良い例は、Cake がモデルを検索する方法です。find()基本的に、すべてのモデルでとの 2 つの方法がありますが、 と の方法をfindAll()使用して検索することもできます。findBy<FieldName>()findAllBy<FieldName>()

たとえば、db テーブルがある場合

notes(id, date, title, body)

そのための Cake モデルを作成します。などのメソッドを使用できfindById()ますfindByTitle()。CamelCase db フィールドのみが必要で、任意のフィールドをより迅速に検索できます。

Cake は__call()魔法の方法を使ってそれを行います。このメソッドは、存在しないメソッドを実行しようとしていて、メソッド名とパラメーターから動的に作成された条件で実行されるfind()場合に呼び出されます。findAll()これは実装が非常に簡単で、実際に多くのメリットを得ることができます。

于 2009-07-25T07:02:24.457 に答える
2

__get()と__set()を使用して、プライベート配列の要素にアクセスします。

class Something {
    private $data;

    public function __set($key, $value) {
        //put validation here
        $this->data[$key] = $value;
    }

    public function __get($key) {
        if (!array_key_exists($this->data, $key)) {
             throw new Exception("Invalid member $key.");
        } else {
             return $this->data[$key];
        }
    }
}

したがって、いくつかの検証を行うと、$ person-> age = "asdf"のようなものはすぐに例外をスローします(ageがパブリックメンバーである場合は問題ありません)。

また、__ set()では、クラスに任意の「メンバー」が必要ない場合に有効なキーを制限できます。

于 2009-07-25T06:45:40.513 に答える
0

Web には、プライベートな「プロパティ配列」を使用し__get()たり、組み合わせたりする例がたくさんあります。__set()クラス定義で私が望んでいた興味深いひねりは、実際にパブリック プロパティを宣言し、これらのマジック インターセプターを引き続き使用できるようにすることです。コードをより自己文書化して、IDE にコード補完などを実行できるようにするためです。通常、これらのプロパティが宣言され、呼び出さ__get()__set()ません。unset()クラスコンストラクターで同じプロパティを使用すると、両方の長所を活かすことができることがわかりました。

于 2009-07-27T04:43:42.843 に答える
0

いくつかのサンプル:

class formatedContainer {
    private $holder;
    protected $mode = "formated";

    public function __set($var, $value) {
        $formated = chunk_split($value, 4, "-");
        if(substr($formated, -1) == "-") 
            $formated = substr($formated, 0, strlen($formated) - 1);
        $this->holder[$var] = array('formated' => $formated, 'plain' => $value);
    }

    public function __get($var) {
        return $this->holder[$var][$this->mode];
    }

    public function getPlain() {
        $this->mode = "plain";
    }

    public function getFormated() {
        $this->mode = "formated";
    }
}

$texts = new formatedContainer();
$texts->myText = md5(uniqid());
$texts->anotherText = md5("I don't change!");

//Prints something like: 440e-6816-b2f5-7aa5-9627-9cc8-26ef-ef3b
echo $texts->myText;

$texts->getPlain();

//Prints something like: 8559d37c5a02714dca8bd1ec50a4603a
echo "<br/>" . $texts->anotherText;

役に立たないかもしれませんが、アイデアを得ることができると思います。:}

于 2009-07-25T02:59:52.867 に答える