PHP が提供する「オーバーロード」とは、クラスの属性とメソッドを動的に「作成」することを指します。私たちはこれを魔法の方法で行います。
現在の環境で未定義または非表示のクラス属性またはメソッドが呼び出された場合、オーバーロードされたメソッドが呼び出されます。
オーバーロードされたメソッドはすべて public に宣言する必要があります。
注:
1) これらのマジック メソッドのパラメータは参照渡しできません。
2) PHP の「オーバーロード」は、他のほとんどのオブジェクト指向言語とは異なります。従来の「オーバーロード」は、同じ名前の複数のクラス メソッドを提供するために使用されますが、各メソッドのパラメーターの型と数は異なります。
プロパティのオーバーロード
public void__set(string$name, mixed$value) publicmixed__get(string$name) publicbool__isset(string$name) publicvoid__unset(string$name)
アクセスできないプロパティに値を割り当てるとき、__set() が呼び出されます。
アクセスできないプロパティの値を読み取る場合、__get() が呼び出されます。
アクセスできないプロパティに対して isset() または empty() が呼び出される場合、 __isset() が呼び出されます。
アクセスできないプロパティに対して unset() が呼び出される場合、 __unset() が呼び出されます。
パラメータ $name は、操作される変数の名前を指します。 __set() メソッドの $value パラメーターは、$name 変数の値を指定します。
プロパティのオーバーロードはオブジェクト内でのみ実行できます。静的メソッドでは、これらのマジック メソッドは呼び出されません。したがって、これらのメソッドはいずれも静的として宣言できません。 PHP 5.3.0 では、これらのマジック メソッドを静的として定義すると警告が生成されます。
注:
PHP の代入操作の処理方法により、__set() の戻り値は無視されます。同様に、次のチェーン割り当てでは、__get() は呼び出されません:
$a = $obj->b = 8;
注:
は isset() を除く他の言語構造で使用されます。で使用されます。これは、オーバーロードされたプロパティで empty() が使用される場合、オーバーロードされたマジック メソッドは呼び出されないことを意味します。
この制限を回避するには、オーバーロードされた属性をローカル変数に割り当ててから、empty() を使用する必要があります。
例 #1 属性のオーバーロードに __get()、__set()、__isset()、__unset() を使用します
class PropertyTest{ /*被重载的数据保存在此*/ private $data = array(); /*重载不能被用在已经定义的属性*/ public $declared = 1; /*只有从类外部访问这个属性时,重载才会发生*/ private $hidden = 2; public function __set($name,$value) { echo "Setting '$name' to '$value'<br>"; $this->data[$name] = $value; } public function __get($name) { echo "Getting '$name'<br>"; if(array_key_exists($name,$this->data)){ return $this->data[$name]; } $trace = debug_backtrace(); trigger_error('未知属性 via __get():'.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); return null; } /*PHP5.1.0之后的版本*/ public function __isset($name){ echo "Is '$name' set?<br>"; return isset($this->data[$name]); } /*PHP5.1.0之后的版本*/ public function __unset($name){ echo "Unsetting '$name'<br>"; unset($this->data[$name]); } /*非魔术方法*/ public function getHidden(){ return $this->hidden; } } echo '<pre class="brush:php;toolbar:false">'; $obj = new PropertyTest; $obj->a = 1; echo $obj->a.'<br>'; var_dump(isset($obj->a)); unset($obj->a); echo '<br>'; echo $obj->declared.'<br>'; echo "Let's experiment with the private property named 'hidden':<br>"; echo "Privates are visible inside the class,so __set() not used...<br>"; echo $obj->getHidden().'<br>'; echo "Privates not visible outside of class,so __get() is used...<br>"; echo $obj->hidden;
出力結果:
Setting 'a' to '1'
Getting 'a'
1
「a」は設定されていますか?
bool(true)
「a」の設定を解除します
1
「hidden」という名前のプライベートプロパティを試してみましょう:
プライベートはクラス内で表示されるため、__set()は使用されません。 ..
2
プライベートはクラスの外では見えないので、__get()が使用されます...
「非表示」の取得
メソッドのオーバーロード
public mixed __call ( string$name , array$arguments ) public static mixed __callStatic ( string$name , array$arguments )
オブジェクト内でアクセスできないメソッドを呼び出す場合、__call()はと呼ばれた。
静的モードでアクセスできないメソッドを呼び出すと、__callStatic() が呼び出されます。
$name パラメータは、呼び出されるメソッドの名前です。 $arguments パラメータは、メソッド $name に渡されるパラメータを含む列挙配列です。
例 #2 __call() と __callStatic() を使用してメソッドをオーバーロードします
class MethodTest { public function __call($name,$arguments) { //注意:$name的值区分大小写 echo "Calling object method '$name' ".implode(',',$argument).'<br>'; } //PHP5.3.0之后的版本 public static function __callStatic($name,$arguments) { //注意:$name的值区分大小写 echo "Calling static method '$name' ".implode(',',$argument).'<br>'; } } $obj = new MethodTest; $obj -> runTest('in object context'); MethodTest::runTest('in static context');
出力結果:
オブジェクト メソッド 'runTest' の呼び出し
オブジェクト メソッド 'runTest' の呼び出し