函数内部的“ static”关键字?


Answers:


155

它使函数记住$has_run多次调用之间给定变量的值(在您的示例中)。

您可以将其用于不同的目的,例如:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

在此示例中,if只能执行一次。即使doStuff会发生多次呼叫。


4
另外,如果该函数运行一次,则不会在以后的调用中将$cacheto 的值重置null,对吗?
user151841 2011年

7
@ user151841 $cache仅在两次请求之间被重置。因此,是的,在同一请求(或脚本执行)中,以后的调用不会重置它。
Yoshi

14
@Muhammad,因为这就是关键字static的作用。
Yoshi

2
我相信if条件检查$cache === null会在每次调用此函数时执行,但不要以为是否$cache = '..'会执行块代码。
艾瓦拉斯2015年

如果函数是类中的方法,会在实例之间共享静态变量怎么办?
圣地亚哥·亚利桑那州

83

到目前为止似乎没有人提及,同一类的不同实例内的静态变量保持其状态。因此,编写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

1
哎哟! 这不止一次咬我。我希望静态方法仅适用于实例,并提供便笺;但这是错误的思维方式,因为在类的上下文中,“静态”对于整个类而言是意味着。属性,方法和变量。
systemovich

14

给出以下示例:

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

的第一个电话

a(20);

将输出10,然后$v20。该$v函数结束后,该变量不是垃圾回收,因为它是静态(非动态)变量。该变量将保持在其作用域内,直到脚本完全结束。

因此,以下调用

a(15);

将输出20,然后设置$v15


9

静态的工作方式与类相同。该变量在函数的所有实例之间共享。在您的特定示例中,函数运行后,$ 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

?>

3

扩大对杨的回答

如果使用静态变量扩展类,则各个扩展类将保留在实例之间共享的“自己的”引用静态。

<?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_repeat
:2

http://ideone.com/W4W5Qv


1

在函数内部,这static意味着在页面加载期间,每次调用函数时,变量将保留其值。

因此,在您给出的示例中,如果调用一个函数两次,如果将其设置$has_runtrue,则该函数将能够知道该函数先前已被调用,因为它$has_run仍然等于true该函数第二次启动的时间。

static在此上下文中,关键字的用法在PHP手册中进行了说明:http : //php.net/manual/zh/language.variables.scope.php

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.