2011-05-31 35 views
79

我正在查看Drupal 7的源代碼,並且發現了一些我以前沒見過的東西。我在php手冊中做了一些初步的研究,但沒有解釋這些例子。`static`關鍵字裏面的函數?

關鍵字static對函數內的變量做什麼?

function module_load_all($bootstrap = FALSE) { 
    static $has_run = FALSE 
+6

http://php.net/manual/en/language.variables.scope.php – Mahesh 2011-05-31 14:26:25

回答

110

它使函數在多個調用之間記住給定變量的值(在您的示例中爲$has_run)。

您可以使用此爲不同的目的,例如:

function doStuff() { 
    static $cache = null; 

    if ($cache === null) { 
    $cache = '%heavy database stuff or something%'; 
    } 

    // code using $cache 
} 

在這個例子中,if將只執行一次。即使多次撥打doStuff也會發生。

+3

另外,如果函數運行一次,也不會在稍後的調用中將'$ cache'的值重置爲'null',對吧? – user151841 2011-07-06 14:18:01

+7

@ user151841'$ cache'只會在請求之間重置。所以是的,它不會在相同的請求(或腳本的執行)中被重置*。 – Yoshi 2011-07-06 14:23:16

+2

爲什麼變量$ cache在第二次調用時沒有重新初始化爲空? – Muhammad 2014-03-13 08:09:32

1

在函數內部,static表示每次在頁面加載期間調用該函數時該變量將保留其值。

因此在本例中,你已經給了,如果你調用一個函數的兩倍,如果它設置$has_runtrue,則函數就能夠知道它以前被稱爲因爲$has_run仍然是等於true時該功能第二次啓動。 http://php.net/manual/en/language.variables.scope.php

13

考慮下面的例子:

function a($s){ 
    static $v = 10; 
    echo $v; 
    $v = $s; 
} 

a(20); 

將輸出的第一次調用

static關鍵字在這方面的用量是PHP手冊這裏解釋10,然後$v20。變量$v在函數結束後不會被垃圾收集,因爲它是一個靜態(非動態)變量。該變量將保持在其範圍內,直到腳本完全結束。

因此,

a(15); 

然後將輸出20下面的調用,然後設置$v15

8

靜態的工作方式與在課堂上的相同。該變量在函數的所有實例中共享。在你的例子中,一旦函數運行,$ has_run被設置爲TRUE。該函數的所有未來運行將具有$ has_run = TRUE。這在遞歸函數中非常有用(作爲傳遞計數的替代方法)。

靜態變量只存在於 本地函數範圍,但它不會 失去當程序執行 離開這個範圍內它的價值。

請參閱在功能http://php.net/manual/en/language.variables.scope.php

3

靜態變量意味着無論你有多少次調用函數的話,只有1個變量。

<?php 

class Foo{ 
    protected static $test = 'Foo'; 
    function yourstatic(){ 
     static $test = 0; 
     $test++; 
     echo $test . "\n"; 
    } 

    function bar(){ 
     $test = 0; 
     $test++; 
     echo $test . "\n"; 
    } 
} 

$f = new Foo(); 
$f->yourstatic(); // 1 
$f->yourstatic(); // 2 
$f->yourstatic(); // 3 
$f->bar(); // 1 
$f->bar(); // 1 
$f->bar(); // 1 

?> 
50

似乎沒有人提到過,同一類的不同實例中的靜態變量仍保持其狀態。所以在編寫OOP代碼時要小心。

考慮一下:

class Foo 
{ 
    public function call() 
    { 
     static $test = 0; 

     $test++; 
     echo $test . PHP_EOL; 
    } 
} 

$a = new Foo(); 
$a->call(); // 1 
$a->call(); // 2 
$a->call(); // 3 


$b = new Foo(); 
$b->call(); // 4 
$b->call(); // 5 

如果你想有一個靜態變量來記住它的狀態,只對當前的類實例,你最好堅持一個類屬性,像這樣:

class Bar 
{ 
    private $test = 0; 

    public function call() 
    { 
     $this->test++; 
     echo $this->test . PHP_EOL; 
    } 
} 


$a = new Bar(); 
$a->call(); // 1 
$a->call(); // 2 
$a->call(); // 3 


$b = new Bar(); 
$b->call(); // 1 
$b->call(); // 2 
2

爲了擴大the answer of Yang

如果擴展與靜態變量的一類,個別延長班將舉行多數民衆贊成插件之間共享「自己」引用靜態tances。

<?php 
class base { 
    function calc() { 
     static $foo = 0; 
     $foo++; 
     return $foo; 
    } 
} 

class one extends base { 
    function e() { 
     echo "one:".$this->calc().PHP_EOL; 
    } 
} 
class two extends base { 
    function p() { 
     echo "two:".$this->calc().PHP_EOL; 
    } 
} 
$x = new one(); 
$y = new two(); 
$x_repeat = new one(); 

$x->e(); 
$y->p(); 
$x->e(); 
$x_repeat->e(); 
$x->e(); 
$x_repeat->e(); 
$y->p(); 

輸出:

之一:1
:1
之一:2
一個:3 < - x_repeat
之一:4
一個:5 < - x_重複
:2

http://ideone.com/W4W5Qv

相關問題