php中的static

靜態成員是一種類變量,可以把它看成時屬於整個類而不是屬於類的某個實例。與一般的實例變量不同的是,靜態成員隻保留一個變量值,而這個變量值對所有的實例都是有效的,也就是說,所有的實例共享這個成員。

$this隻表示類的當前實例,而 self:: 表示的是類本身,在類之外的代碼中不能使用這個操作符,而且它不能識別自己在繼承樹層次結構中的位置。也就是說,在擴展類中使用self 作用域時,self 可以調用基類中聲明的方法,但它調用的總是已經在擴展類中重寫的方法。與$this不同的是,在使用靜態變量時,必須在作用域限定符後面加上$符號。

在擴展類中,在基類的方法被重寫的情況下,使用 parent 作用域調用定義在基類中的方法。靜態成員也可以隻屬於父類。如果在子類和父類中同時聲明瞭某個成員,也可以使用parant::在子類中訪問父類中的變量。在這種情況下,父類的靜態成員和子類的靜態成員保存的是不同的值。

可以在 :: 操作符的左邊寫上類的名稱來靜態地訪問某個成員,這樣避免創建類的實例。不僅省略掉實例化類的代碼,而且還會更高效,因為類的每個實例都會占用一小部分的系統資源。

在使用 :: 操作符訪問成員變量時,需要再次註意對$符號的使用。因為PHP當前不支持動態的靜態變量的使用,也就是說不支持可變的靜態變量。在使用$this->$var時,被訪問的成員是包含在$var中的變量的值。而不用$符號訪問某個變量實際上查找的是類的某個常量,而常量是不能通過$this來訪問的。

PHP6中提出的static::作用域使我們不再需要使用self::和parent::。當希望指向最終的實現功能的類時,就可以使用static::,這個限定符會在代碼執行之前立即計算出繼承層次機構上最後那個類的成員。之一過程被稱為延遲綁定,它使我們可以在子類中重寫某個靜態變量,並且也可以從某個在父類中聲明的函數中反問這個最終成員。

有時,可能有必要創建供所有類實例共享的字段和方法,這些字段和方法與所有的類實例有關,但不能由任何特定對象調用。例如,假設要編寫一個類,跟蹤網頁訪問者的數量。你一定不希望每次實例化該類時都把訪問者數量重置為0 ,此時就可以將該字段設置為static作用域:

復制代碼

<?php
    class visitors
    {
        private static $visitors = 0;
        function __construct()
        {
             self::$visitors++;
        }
        static function getVisitors()
        {
            return self::$visitors;
        }
    }
    /* Instantiate the visitors class. */
    $visits = new visitors();
    echo visitors::getVisitors()."
"; /* Instantiate another visitors class. */ $visits2 = new visitors(); echo visitors::getVisitors()."
"; ?>

復制代碼

程式運行結果:

1

2

因為$visitors字段聲明為static,所以對其值的任何改變都會反映到所有實例化對象中。還要註意,靜態字段和方法應使用self關鍵字和類名來引用,而不是通過this和箭頭操作符。這是因為使用“正常”方法引用靜態字段是不可能的,會導致語法錯誤。

不能在類中使用$this來引用為static字段。

靜態變量

靜態變量是隻存在於函數作用域的變量,不過,在函數執行完成後,這種變量的值不會丟失,也就是說,在下一次調用這個函數時,變量仍然會記得原來的值。要將某個變量定義為靜態的,隻需要在變量前加上 static 關鍵字即可。

在類中,static關鍵字有兩種主要用法,一是用來定義靜態成員,一是用來定義靜態方法。在類的內部,可以使用作用域限定符 (::) 來訪問不同層次作用域的變量。

靜態方法

靜態方法和非靜態方法之間有一個重要的區別:在調用靜態方法時,不再需要擁有類的實例。

靜態方法和非靜態方法使用原則:一是如果某個方法中不包含$this變量,就應該時靜態方法;如果不需要類的實例,可能還應該使用靜態類,這樣可以免去實例化類的工作。另,在靜態方法中時不能使用$this變量的,因為靜態方法不屬於某個特定的實例。

發佈留言