面向物件特殊實踐
(只有在PHP裡面才有,其他語言面向物件沒有)
面向物件--魔術方法
__construct(), __destruct() 建構子與析構函數
__tostring)
__invoke()
__call(), __callStatic()
__get(), __set(), __isset(), __unset()
__clone()
__tostring()
當String會被自動呼叫。
Echo $obj;
__invoke()
當物件被當成方法呼叫時,這個方法會被自動呼叫
$obj(4);
<?php class MagicTest{ //__tostring会在把<strong>对象</strong>转换为string的时候自动调用 public function __tostring(){ return "This is the Class MagicTest. "; } // __invoke会在把<strong>对象</strong>当作一个方法调用的时候自动调用 public function __invoke($x){ echo "__invoke called with parameter ".$x."\n"; } } $obj = new MagicTest(); echo $obj."\n"; $obj(5); ?>
<?php class MagicTest{ public function __tostring(){ return "This is the Class MagicTest. "; } public function __invoke($x){ echo "__invoke called with parameter ".$x."\n"; } //方法的重载 //这个方法的参数第一个就是调用的方法的名称,第二个参数是方法调用的参数组成的数组 public function __call($name,$arguments){ echo "Calling " . $name . " with parameters: ". implode(",", $arguments)."\n"; } //<strong>静态方法</strong>的重载,注意这个方法需要设定为static public static function __callStatic($name,$arguments){ echo "Static Calling " . $name . " with parameters: ". implode(",", $arguments)."\n"; } } $obj = new MagicTest(); //runTest这两个方法的名称本来不能完全相同,但是通过魔术方法,可以调用了 $obj->runTest("para1","para2"); //没有声明这个runTest方法,因为有__call这个魔术方法,也可以被调用 MagicTest::runTest("para1","para2"); //没有声明这个runTest方法,因为有__callStatic这个魔术方法,也可以被调用 ?>
__call()當物件
存取不存在的方法名稱時,__call()方法會被自動呼叫
__callStatic()當。時,__callStatic()方法會被自動呼叫這兩個方法在PHP裡面也被成為方法的重載(overloading)注意區分重寫(overwrite)
通過這兩個方法,同一個方法的名稱的調用可以對應不同的方法實作
<?php class MagicTest{ public function __tostring(){ return "This is the Class MagicTest. "; } public function __invoke($x){ echo "__invoke called with parameter ".$x."\n"; } //方法的重载 //这个方法的参数第一个就是调用的方法的名称,第二个参数是方法调用的参数组成的数组 public function __call($name,$arguments){ echo "Calling " . $name . "with parameters: ". implode(",", $arguments)."\n"; } //<strong>静态方法</strong>的重载,注意这个方法需要设定为static public static function __callStatic($name,$arguments){ echo "Static Calling " . $name . "with parameters: ". implode(",", $arguments)."\n"; } //属性重载 public function __get($name){ return "Getting the property ".$name."\n"; } public function __set($name, $value){ echo "Setting the property ".$name." to value " . $value."\n"; } public function __isset($name){ echo "__isset invoked\n"; return true; } public function __unset($name){ echo "unsetting property ".$name."\n"; } } $obj = new MagicTest(); echo $obj->className."\n"; //className未定义,但是通过魔术方法__get,这个方法好像被定义了一样 $obj->className='MagicClassX'; //通过魔术方法__get将className名称定义为MagicClassX echo '$obj->name is set?'.isset($obj->className)."\n"; echo '$obj->name is empty?'.empty($obj->className)."\n"; unset($obj->className); ?>
Static Calling runTest with parameters: para1,para2
)
在賦值不可存取屬性時,__set()會被呼叫
當對不可存取屬性呼叫isset()或empty()時,__isset( )會被呼叫
當對不可存取屬性呼叫unset()時,__unset()會被呼叫
所謂不可存取屬性,其實就是在呼叫某個屬性是發現這個屬性沒有被定義,這時候不同的操縱會觸發不同的魔術方法
這幾個方法也被稱為屬性重載的魔術方法
<?php class NbaPLayer{ public $name; function __clone(){ $this->name='TBD'; //屏蔽你不想要他复制过去的数据,屏蔽掉他的数据,设置他的初始值 } } $james = new NbaPlayer(); $james->name = 'James'; echo $james->name."\n"; $james2 = clone $james; echo "Before set up: James2's: ".$james2->name."\n"; $james2->name='James2'; echo "James's: ".$james->name; echo "James's: ".$james2->name; ?>
Setting the property className to value MagicClassX name-cobof namek-name-Scobo_Fet MagicClassX name. is set?1 //如果return為true的話,結果顯示為1;如果return為false的話,結果顯示為空
__isset invoked
$obj->name is empty? //如果return為true的話,結果顯示為空;如果return為false的話,結果顯示為1
unsetting property className
面向
物件
--魔術方法
__clone()
rrreee
output:
James James2的數據不會影響James的數據