プライベート変数の使用とアクセスに関するこの質問から、一般的な使用方法についての情報を入手したいと思います。オーバーロード関数を使用するのに最適な時期と場所、および使用した場所(ある場合)について疑問に思っています。__get()
__set()
明確にするために、これらの関数について話します:http: //us2.php.net/manual/en/language.oop5.magic.php
プライベート変数の使用とアクセスに関するこの質問から、一般的な使用方法についての情報を入手したいと思います。オーバーロード関数を使用するのに最適な時期と場所、および使用した場所(ある場合)について疑問に思っています。__get()
__set()
明確にするために、これらの関数について話します:http: //us2.php.net/manual/en/language.oop5.magic.php
自分のアプリで PHP のマジック メソッドをあまり頻繁に使用した覚えはありませんが、ある状況で__get()
非常に便利だったことは覚えています。
昔、私はCakePHPフレームワークでアプリケーションを開発していました.CakePHPフレームワークには多くのモデルがあり、特定のコントローラーで使用されるすべてのモデルは、メソッドがそれらのうちの1つまたは2つしか使用しない場合でも初期化されました(Cakeの動作方法です)。そこで、これを遅延モデルに変更することにしました (モデルが初めて使用されるときにモデルをロードします)。
私がしたことは__get()
、特定の名前のモデルを探してロードする非常に単純な関数を追加したことだけです。3 ~ 4 行のコードでした。AppController (すべての CakePHP クラスはそのコントローラーから派生します) でそれを定義すると、突然、アプリの速度が上がり、メモリの使用量が減りました。
後でそれをさらに進めて、同じ方法で遅延コンポーネントの読み込みも行いました。
同じく 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()
これは実装が非常に簡単で、実際に多くのメリットを得ることができます。
__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()では、クラスに任意の「メンバー」が必要ない場合に有効なキーを制限できます。
Web には、プライベートな「プロパティ配列」を使用し__get()
たり、組み合わせたりする例がたくさんあります。__set()
クラス定義で私が望んでいた興味深いひねりは、実際にパブリック プロパティを宣言し、これらのマジック インターセプターを引き続き使用できるようにすることです。コードをより自己文書化して、IDE にコード補完などを実行できるようにするためです。通常、これらのプロパティが宣言され、呼び出さ__get()
れ__set()
ません。unset()
クラスコンストラクターで同じプロパティを使用すると、両方の長所を活かすことができることがわかりました。
いくつかのサンプル:
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;
役に立たないかもしれませんが、アイデアを得ることができると思います。:}