首頁 php教程 php手册 1.2魔術方法和延遲靜態綁定

1.2魔術方法和延遲靜態綁定

Aug 23, 2016 am 09:03 AM

一.魔術方法:

  1.__get,__set

  __get:取得一個不可存取的屬性時觸發(不可存取指屬性不存在,或沒有存取權限)

  __set:為一個不可存取的屬性賦值的時候觸發

  2.__isset,__unset

  __isset:當用isset()函數判斷一個不可存取的屬性時觸發

  __unset:當用unset()函數操作一個不可存取的屬性時觸發

  3.__call,__callStatic

  __call:當呼叫一個不可存取的方法時觸發

  __callStatic:當呼叫一個不可存取的靜態方法時觸發

  4.__construct,__destruct

  __construct:初始化一個物件時觸發

  __destruct:物件銷毀,或腳本執行完時觸發

  5.__autoload

  __autoload:當使用一個不可訪問的類別時觸發

  6.__clone

  __clone:物件被複製時觸發

  7.__sleep,__wakeup

  __sleep:使用serialize時觸發

  __wakeup:使用unserialize時觸發

  8.__toString,__invoke

  __toString:當一個物件被當做字串來操作時觸發,如$obj是一個物件,echo $obj,就會觸發__toString

  __invoke:當一個物件被當做函數來使用時觸發,如$obj是一個物件,$obj()就會觸發__invoke

 

二.延遲靜態綁定

  拋開概念看例子理解就好:

  先延遲靜態綁定是怎麼出現的?看下面例子:

class A{<br>}<br>class B extends A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>class C extends A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>var_dump(B::out());//结果是object(B)#1 (0) { }<br>var_dump(C::out());//结果是object(C)#1 (0) { }<br>然后我们将子类中相同的代码抽取到父类class A中,变成:
登入後複製
class A{<br>    public static function out(){<br>        return new self();<br>    }<br>}<br>class B extends A{<br>}<br>class C extends A{<br>}<br>var_dump(B::out());//结果是object(A)#1 (0) { }<br>var_dump(C::out());//结果是object(A)#1 (0) { }<br>这个结果显然不是我们想要的,这里的问题主要是因为self指代的是它所在的类.这里self在类A里面,所以返回的永远是类A的对象,<br>而我们想要的是让out()方法返回调用它的类的对象而不是它所在的类的对象.怎么办?<br>此时我们马上可以想到$this可以代表调用它的对象,但是out()是一个静态方法,里面是不能出现$this的,怎么办?<br>用static.它也代表调用它的对象如:
登入後複製
class A{<br>    public static function out(){<br>        return new static();<br>    }<br>}<br>class B extends A{<br>}<br>class C extends A{<br>}<br>var_dump(B::out());//结果是object(B)#1 (0) { }<br>var_dump(C::out());//结果是object(C)#1 (0) { }<br>这样就好了.这就是延迟静态绑定.<br><br>在看下面的例子:
登入後複製

為什麼是這個結果呢?我們分析一下:

首先物件c呼叫get()方法,但是在類別C中沒有找到,於是它去類別B中找,找到了.然後執行這個get方法,

先執行A::foo(); 類別A會直接呼叫它自己的foo(),輸出`fooA`,然後呼叫out,很明顯這裡呼叫static::out()的就是類別A,所以輸出的類名也是A.(這裡著重於類A)

再執行parent::foo(); parent表示父類別,這裡會去執行類別A中的foo(),輸出`fooA`,然後執行static::out(),此時呼叫這個static的不是類別A ,而是類別C,因為parent代表的是父類別,但不代表具體哪一個類別(這裡側重於父類別中的方法,而不管父類別是誰).

然後執行self::foo(); self表示它所在的類別(類別B),它先執行foo(),沒有再去父類別中找,所以輸出`fooA`,然後執行static::out() ,同理這裡使用static的不是類A,而是類C,self雖然代表類B,但是self不能代表一個具體的類.

簡單點說:物件c開始執行get()-->A::foo();此時鍊子就斷了,變成由類別A直接去呼叫foo()了,和物件c沒關係了.這裡的static當然指的是類A.

     接著,對象c-->parent::foo()-->類別A中的foo()-->static::out(),這裡的parent說白了就是一個指向作用,即執行誰的foo( )方法.所以可以理解為物件c呼叫類別A中的foo方法.那麼foo中的static代表類別C

     最後,物件c-->self::foo()-->類別A中的foo()-->static::out(),同上,這裡的self也是一個指向的作用,但是最終還是到了類A.可以理解為物件c呼叫類別A中的foo方法.那麼foo中的static代表類別C

 

登入後複製
<br><br>
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1250
24