1. 程式人生 > >php中Static(靜態)關鍵字作用

php中Static(靜態)關鍵字作用

1、什麼是static?

static 是C++中很常用的修飾符,它被用來控制變數的儲存方式和可見性。但在PHP中用 static 關鍵字來定義靜態方法和屬性, 也可用於定義靜態變數以及後期靜態繫結。

2、為什麼要引入static?

函式內部定義的變數,在程式執行到它的定義處時,編譯器為它在棧上分配空間,大家知道,函式在棧上分配的空間在此函式執行結束時會釋放掉,這樣就產生了一個問題: 如果想將函式中此變數的值儲存至下一次呼叫時,如何實現? 最容易想到的方法是定義一個全域性的變數,但定義為一個全域性變數有許多缺點,最明顯的缺點是破壞了此變數的訪問範圍(使得在此函式中定義的變數,不僅僅受此函式控制)。

3、什麼時候用static?

需要一個數據物件為整個類而非某個物件服務,同時又力求不破壞類的封裝性,即要求此成員隱藏在類的內部,對外不可見。

4、static的內部機制:

靜態資料成員要在程式一開始執行時就必須存在。因為函式在程式執行中被呼叫,所以靜態資料成員不能在任何函式內分配空間和初始化。
這樣,它的空間分配有三個可能的地方,一是作為類的外部介面的標頭檔案,那裡有類宣告;二是類定義的內部實現,那裡有類的成員函式定義;三是應用程式的main()函式前的全域性資料宣告和定義處。
靜態資料成員要實際地分配空間,故不能在類的宣告中定義(只能宣告資料成員)。類宣告只宣告一個類的“尺寸和規格”,並不進行實際的記憶體分配,所以在類宣告中寫成定義是錯誤的。它也不能在標頭檔案中類宣告的外部定義,因為那會造成在多個使用該類的原始檔中,對其重複定義。
static被引入以告知編譯器,將變數儲存在程式的靜態儲存區而非棧上空間,靜態資料成員按定義出現的先後順序依次初始化,注意靜態成員巢狀時,要保證所巢狀的成員已經初始化了。消除時的順序是初始化的反順序。

5、static的優勢:

可以節省記憶體,因為它是所有物件所公有的,因此,對多個物件來說,靜態資料成員只儲存一處,供所有物件共用。靜態資料成員的值對每個物件都是一樣,但它的值是可以更新的。只要對靜態資料成員的值更新一次,保證所有物件存取更新後的相同的值,這樣可以提高時間效率。

6、引用靜態資料成員時,採用如下格式:

<類名>::<靜態成員名>
如果靜態資料成員的訪問許可權允許的話(即public的成員),可在程式中,按上述格式來引用靜態資料成員

7、注意事項:

(1)類的靜態成員函式是屬於整個類而非類的物件,所以它沒有this指標,這就導致了它僅能訪問類的靜態資料和靜態成員函式。由於靜態方法不需要通過物件即可呼叫,所以偽變數 $this 在靜態方法中不可用。靜態屬性不可以由物件通過 -> 操作符來訪問。用靜態方式呼叫一個非靜態方法會導致一個 E_STRICT 級別的錯誤。
(2)不能將靜態成員函式定義為虛擬函式。
(3)由於靜態成員聲明於類中,操作於其外,所以對其取地址操作,就多少有些特殊,變數地址是指向其資料型別的指標,函式地址型別是一個“nonmember函式指標”。
(4)由於靜態成員函式沒有this指標,所以就差不多等同於nonmember函式,結果就產生了一個意想不到的好處:成為一個callback函式,使得我們得以將C++和C-based X Window系統結合,同時也成功的應用於執行緒函式身上。
(5)static並沒有增加程式的時空開銷,相反她還縮短了子類對父類靜態成員的訪問時間,節省了子類的記憶體空間。
(6)靜態資料成員在<定義或說明>時前面加關鍵字static。
(7)靜態資料成員是靜態儲存的,所以必須對它進行初始化。
(8)靜態成員初始化與一般資料成員初始化不同:
初始化在類體外進行,而前面不加static,以免與一般靜態變數或物件相混淆;
初始化時不加該成員的訪問許可權控制符private,public等;
初始化時使用作用域運算子來標明它所屬類;
所以我們得出靜態資料成員初始化的格式:
<資料型別><類名>::<靜態資料成員名>=<值>
(9)為了防止父類的影響,可以在子類定義一個與父類相同的靜態變數,以遮蔽父類的影響。這裡有一點需要注意:我們說靜態成員為父類和子類共享,但我們有重複定義了靜態成員,這會不會引起錯誤呢?不會,我們的編譯器採用了一種絕妙的手法:name-mangling 用以生成唯一的標誌。

8.實踐

靜態屬性與方法示例
<?php
class Foo
{
    public static $my_static = 'foo';

    public function staticValue() {
        return self::$my_static;
    }
    public static function output() {
        return self::$my_static;
    }
}

class Bar extends Foo
{
    public function fooStatic() {
        return parent::$my_static;
    }
}


print Foo::$my_static . "\n";
print Foo::output() . "\n";
$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n";      // Undefined "Property" my_static 
print $foo::$my_static . "\n";
靜態變數的例子
<?php
function Test()
{
    $a = 0;
    echo $a;
    $a++;
}
?>
本函式沒什麼用處,因為每次呼叫時都會將 $a 的值設為 0 並輸出 0。將變數加一的 $a++ 沒有作用,因為一旦退出本函式則變數 $a 就不存在了。要寫一個不會丟失本次計數值的計數函式,要將變數 $a 定義為靜態的:
<?php
function test()
{
    static $a = 0;
    echo $a;
    $a++;
}
?>
現在,變數 $a 僅在第一次呼叫 test() 函式時被初始化,之後每次呼叫 test() 函式都會輸出 $a 的值並加一。
靜態變數也提供了一種處理遞迴函式的方法。遞迴函式是一種呼叫自己的函式。寫遞迴函式時要小心,因為可能會無窮遞迴下去。必須確保有充分的方法來中止遞迴。以下這個簡單的函式遞迴計數到 10,使用靜態變數 $count 來判斷何時停止:
<?php
function test()
{
    static $count = 0;

    $count++;
    echo $count;
    if ($count < 10) {
        test();
    }
    $count--;
}
?>

相關推薦

phpStatic靜態關鍵字作用

1、什麼是static? static 是C++中很常用的修飾符,它被用來控制變數的儲存方式和可見性。但在PHP中用 static 關鍵字來定義靜態方法和屬性, 也可用於定義靜態變數以及後期靜態繫結。 2、為什麼要引入static? 函式內部定義的變數,

Djangostatic靜態檔案詳解以及{% static %}標籤的使用

想要深入學習Django的可以看一些這個視訊:超細講解Django打造大型企業官網 在一個網頁中,不僅僅只有一個html骨架,還需要css樣式檔案,js執行檔案以及一些圖片等。因此在DTL中載入靜態檔案是一個必須要解決的問題。在DTL中,使用static標籤來載入靜態檔案。要使用stat

static靜態關鍵字的特點和用法

→靜態:static 用法:是一個修飾符,用於修飾成員(成員變數,成員函式) class Person {     String country = "cn"; } /*每例項化一個Person物件,每個物件在堆記憶體中都有一個country 而加上static以後,就只在記憶體總存在一個靜態的country

C++基礎之static靜態變量

引用 靜態成員 頭文件 this指針 文件中 單元 一份 文件無效 全局 static 表示靜態 作用: 1、在函數體內,靜態變量的值維持不變(記憶功能) 2、是一個本地的全局函數,即只能被本模塊的函數訪問(隱藏功能) static變量: static全局變量和普通

什麽是static靜態基礎詳解

一個 特點 代碼塊 就是 場景 類名 但是 消失 變量 static修飾成員變量 如果有數據需要被共享給所有對象使用時,那麽就可以使用static修飾。靜態成員變量的訪問方式 方式1: 可以使用對象進行訪問。 格式: 對象.變量名。 方式

CSS浮動Float作用

課程關鍵詞:浮動 頁面佈局有兩種方式 引用: 1)浮動Float  2)定位Position 今天就來一個小小的練習,讓大家理解Float的含義 複製內容到剪貼簿 程式碼: 【例子】 要求: 1)兩個方塊,一個紅色#900,一個藍色#009; 2)紅色方塊寬度

PHP 偽變數$this->作用域操作符:: 的是使用

<?php header("Content-Type: text/html; charset=utf-8"); /** * */ class Test

static靜態成員與非靜態變數和普通成員方法的關係

1.static ( 被其修飾的是靜態成員類成員,屬於整個類所有,不是針對某個物件即類中所有物件所有。           可以使用類名訪問,也可以使用物件名訪問 ) 使用之靜態變數   static可修飾變數、方法、程式碼塊   1)靜態成員(方法)能直接呼叫(訪問)靜態成

.NET多線程之線程安全,Lock、Monitor同步訪問、LazyInitializer延遲初始化、Interlocked原子操作static靜態構造函數、volatile、

called val www. queue 多線程 try 退出 con 內存 1、什麽是線程安全    線程安全是編程中的術語,指某個函數、函數庫在多線程環境中被調用時,能夠正確地處理多個線程之間的共享變量,使程序功能正確完成。一般來說,線程安全的函數應該為每個調用它的

【轉】PHP的後期靜態綁定Late Static Bindings

mbo 代碼 當前 test num ngs color public name php5.3版本新增的靜態綁定的靜態綁定語法,也成為PHP的後期靜態綁定,如下 class A{ public static function func1(){ e

php名稱空間namespace作用和使用

1.名稱空間的作用: 在PHP中函式、類、常量是不允許同名的。為了解決這三者的同名問題,所以出現了名稱空間. 其實不僅僅是php,其他語言也有類似的使用。比如JavaScript中: 我們來詳細的講解一下PHP中的名稱空間: 語法:namespace 空間名\空間名;

static 關鍵字靜態

1.具體作用好處我還不知道 2.用法:當給方法或者屬性(欄位) 加上static 關鍵字                       就可以不建立物件,直接用類名呼叫              例: public class Test {     static int

PHP實戰技巧11PHP靜態知識:靜態類屬性、方法

evel 變量 結果 其他 lan line 並且 功能 lin 前言 靜態變量用的不多,但是靜態的類屬性、類方法,則是工作中必不可少的一個知識點。 基礎語法 先看代碼,下面逐一進行解釋。 “::” 是什麽? 它是兩組冒號,調用靜態資源專屬

phpstatic和self調用靜態方法區別

php由於看到框架裏面經常使用static::method() 於是稍微了解下static和self的區別廢話少說,直接上代碼class Father { public function __construct() { $this->init(); self::test(); }

Java靜態變數、靜態程式碼塊的執行順序包含父類

1、parent類(父類) public class parent { public static int parentParamOne = 1; public static String parentParamTwo = "two1111"; static{

javabyte負值作&運算時0xff的作用

1.問題由來 專案中遇到一個將byte位元組流轉換成有符號整數和無符號整數的,發現: byte aByte = ByteBuffer.get();----對應的二進位制各位 如果byte為正數:int

java static,final,transient,volatile關鍵字作用

static 和final   static  靜態修飾關鍵字,可以修飾 變數,程式塊,類的方法;  當你定義一個static的變數的時候jvm會將將其分配在記憶體堆上,所有程式對它的引用都會指向這一個地址而不會重新分配記憶體; 修飾一個程式塊的時候(也就是直接將程式碼寫在

Mavendependency依賴的scope作用

一、作用域列舉 Maven官網介紹: There are 6 scopes available: compile This is the default scope, used if none is specified. Compile dependencies are avail

java分派靜態分派,動態分派,雙重分派討論

以上資訊來自於java修煉手冊(好書)概念:變數被宣告時的型別叫做變數的明顯型別,也稱為靜態型別變數所引用的物件的真實型別叫做實際型別靜態分派:發生在編譯時期,分配根據靜態型別發生,方法的過載就是靜態分派動態分派:發生在執行時期,動態的置換掉某個方法靜態分派例項講解:動態分派

phpstatic 靜態變數和普通變數的區別

1、在變數的前面加上static 就構成了靜態變數(static 變數)。 2、static變數和普通變數的區別在於非靜態全域性變數的作用域是整個源程式,當一個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是有效的。 而靜態全域性變數則限制了其作用域, 即只在定義該變數的原始檔內有效, 在同一源