2011-05-31 93 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