這篇文章主要介紹了關於利用PHP的作用域解析運算子(::),有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
今天看joomla源碼的時候,才意識到。原來這個運算子還可以存取類別的非靜態方法啊。真的讓我吃驚不好。一直以為作用域解析運算子只能存取類別的static方法和static成員變數。
Scope Resolution Operator (::)
今天 看joomla原始碼的時候,才意識到。原來這個運算子還可以存取類別的非靜態方法啊。真的讓我吃驚不好。一直以為作用域解析運算子只能存取類別的static方法和static成員變數。
如果各位不相信,下面有個簡單的小測試程式碼可以證明這個。
class A{ private $_name = 'A'; function __construct(){ echo 'A construct <br />'; } function test(){ echo 'A test() <br />'; } } class B extends A{ private $_name = 'B'; function __construct(){ parent::__construct(); echo 'B construct <br />'; } function test(){ echo 'B test()'; } } A::test(); echo '######### <br />'; B::test();
這段程式碼輸入的結果為:
A test() ######### B test()
雖然A類別中的test()和B類別中的test都不是static方法,但一樣可以用「類別名稱::方法名稱(參數列表)” 的樣式進行正確呼叫。他的效果和 new 一個類別的實例,然後用這個實例呼叫
test方法是一個樣的。
但是,如果我需要在test方法中列印name屬性,直接用::來呼叫 會是怎麼個情況那.我們先來修改下 上面的程式碼。
class A{ private $_name = 'A'; function __construct(){ echo 'A construct <br />'; } function test(){ echo 'A test() <br />', $this->$_name,'<br />'; } } class B extends A{ private $_name = 'B'; function __construct(){ parent::__construct(); echo 'B construct <br />'; } function test(){ echo 'B test()', $this->_name,'<br />'; } } A::test(); echo '######### <br />'; B::test();
上面的程式碼運作的結果 如下:
Fatal error: Using $this when not in object context in D:\www\test\scoperefe.php on line 9 [html]
那有的朋友就說了。你壓根就沒有實例化類別A,當然不能直接用$this->_name的方式來存取成員變數$_name了,那麼,是不是修改成self::$_name就行了哪?
說乾就乾,下面把上面的程式碼修改下
[code] class A{ private $_name = 'A'; function __construct(){ echo 'A construct <br />'; } function test(){ echo 'A test() <br />', self::$_name,'<br />'; } } class B extends A{ private $_name = 'B'; function __construct(){ parent::__construct(); echo 'B construct <br />'; } function test(){ echo 'B test()', $this->_name,'<br />'; } } A::test(); echo '######### <br />'; B::test();
再運行上面的程式碼,結果如下:
A test() Fatal error: Access to undeclared static property: A::$_name in D:\www\test\scoperefe.php on line 9
哦,原來不能用self 關鍵字訪問目前類別的非static方法。
現在,如果想正確的呼叫這個方法,有2個做法:
1、先實例化類,然後用物件呼叫就可以直接使用$this->_name進行呼叫了;
2 、將成員變數$_name設定為static;
上面的問題,相信大家都能夠正確的處理。
其實我真正想說的是:
如果一個方法可以不進行實例化就調用,那我們最好把這個方法使用static關鍵字修飾下。在實作方法的時候,只呼叫該類別的static成員變數。這樣就不會出現上面遇到問題了。
如果一個方法沒有設定為static的方法。那麼,最安全的做法還是用實例物件進行呼叫比較為安全,因為,說不定什麼時候就需要修改該方法的實現,在修改的時候,說不定就要呼叫該類別中的
非static成員變數(因為,很大程度上在修改方法的實作的時候,已經忘記還有用類別名稱直接呼叫這麼一說)。
個人愚見。
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!
相關推薦:
關於PHP自定義序列化介面Serializable的用法分析
#
以上是利用PHP的作用域解析運算子(::)的詳細內容。更多資訊請關注PHP中文網其他相關文章!