首頁  >  文章  >  後端開發  >  利用PHP的作用域解析運算子(::)

利用PHP的作用域解析運算子(::)

不言
不言原創
2018-06-21 09:31:142147瀏覽

這篇文章主要介紹了關於利用PHP的作用域解析運算子(::),有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

今天看joomla源碼的時候,才意識到。原來這個運算子還可以存取類別的非靜態方法啊。真的讓我吃驚不好。一直以為作用域解析運算子只能存取類別的static方法和static成員變數。

Scope Resolution Operator (::)
今天 看joomla原始碼的時候,才意識到。原來這個運算子還可以存取類別的非靜態方法啊。真的讓我吃驚不好。一直以為作用域解析運算子只能存取類別的static方法和static成員變數。
如果各位不相信,下面有個簡單的小測試程式碼可以證明這個。

class A{ 
private $_name = 'A'; 
function __construct(){ 
echo &#39;A construct <br />&#39;; 
} 
function test(){ 
echo &#39;A test() <br />&#39;; 
} 
} 
class B extends A{ 
private $_name = &#39;B&#39;; 
function __construct(){ 
parent::__construct(); 
echo &#39;B construct <br />&#39;; 
} 
function test(){ 
echo &#39;B test()&#39;; 
} 
} 
A::test(); 
echo &#39;######### <br />&#39;; 
B::test();

這段程式碼輸入的結果為: 

A test() 
######### 
B test()

雖然A類別中的test()和B類別中的test都不是static方法,但一樣可以用「類別名稱::方法名稱(參數列表)” 的樣式進行正確呼叫。他的效果和 new 一個類別的實例,然後用這個實例呼叫
test方法是一個樣的。
但是,如果我需要在test方法中列印name屬性,直接用::來呼叫 會是怎麼個情況那.我們先來修改下 上面的程式碼。 

class A{ 
private $_name = &#39;A&#39;; 
function __construct(){ 
echo &#39;A construct <br />&#39;; 
} 
function test(){ 
echo &#39;A test() <br />&#39;, $this->$_name,&#39;<br />&#39;; 
} 
} 
class B extends A{ 
private $_name = &#39;B&#39;; 
function __construct(){ 
parent::__construct(); 
echo &#39;B construct <br />&#39;; 
} 
function test(){ 
echo &#39;B test()&#39;, $this->_name,&#39;<br />&#39;; 
} 
} 
A::test(); 
echo &#39;######### <br />&#39;; 
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 = &#39;A&#39;; 
function __construct(){ 
echo &#39;A construct <br />&#39;; 
} 
function test(){ 
echo &#39;A test() <br />&#39;, self::$_name,&#39;<br />&#39;; 
} 
} 
class B extends A{ 
private $_name = &#39;B&#39;; 
function __construct(){ 
parent::__construct(); 
echo &#39;B construct <br />&#39;; 
} 
function test(){ 
echo &#39;B test()&#39;, $this->_name,&#39;<br />&#39;; 
} 
} 
A::test(); 
echo &#39;######### <br />&#39;; 
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中Yii框架的元件行為的屬性注入與方法注入

關於PHP自定義序列化介面Serializable的用法分析

#

以上是利用PHP的作用域解析運算子(::)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn