`static`关键字里面有什么功能?

use*_*841 102 php static function keyword

我正在查看Drupal 7的来源,我找到了一些我以前没见过的东西.我做了一些初步查看php手册,但它没有解释这些例子.

关键字static对函数内部的变量做了什么?

function module_load_all($bootstrap = FALSE) {
    static $has_run = FALSE
Run Code Online (Sandbox Code Playgroud)

Yos*_*shi 142

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

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

function doStuff() {
  static $cache = null;

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

  // code using $cache
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,if只执行一次.即使多次调用doStuff也会发生.

  • @Muhammad因为这就是关键字[静态](http://php.net/manual/language.oop5.static.php)的作用. (14认同)
  • @ user151841` $ cache`只会在请求之间重置.所以是的,它将不会在同一请求(或执行脚本)的laters调用中重置*. (7认同)
  • 此外,如果函数运行一次,它将不会在以后的调用中将`$ cache`的值重置为`null`,对吗? (4认同)
  • 为什么变量$ cache在第二次调用时没有重新初始化为null? (3认同)
  • 我相信每次调用这个函数时都会执行`if`条件检查`$ cache === null`,不管是否会执行块代码`$ cache ='..'`. (2认同)

Yan*_*ang 72

似乎到目前为止没有人提到过,同一个类的不同实例中的静态变量仍然是它们的状态.编写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
Run Code Online (Sandbox Code Playgroud)

如果您希望静态变量仅记住当前类实例的状态,您最好坚持使用类属性,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

  • 哎哟! 这已经不止一次地咬过我了。我希望静态仅适用于实例,提供记忆;但这是错误的思维方式,因为类上下文中的“静态”意味着整个类。属性、方法和变量。 (2认同)

mau*_*ris 13

给出以下示例:

function a($s){
    static $v = 10;
    echo $v;
    $v = $s;
}
Run Code Online (Sandbox Code Playgroud)

第一次打电话

a(20);
Run Code Online (Sandbox Code Playgroud)

将输出10,然后$v20.$v函数结束后,变量不会被垃圾收集,因为它是一个静态(非动态)变量.变量将保持在其范围内,直到脚本完全结束.

因此,以下调用

a(15);
Run Code Online (Sandbox Code Playgroud)

然后输出20,然后设置$v15.


tof*_*tim 8

Static的工作方式与在类中的工作方式相同.该变量在函数的所有实例中共享.在您的特定示例中,一旦运行该函数,$ has_run将设置为TRUE.该函数的所有未来运行都将具有$ has_run = TRUE.这在递归函数中特别有用(作为传递计数的替代方法).

静态变量仅存在于本地函数作用域中,但在程序执行离开此作用域时它不会丢失其值.

http://php.net/manual/en/language.variables.scope.php


Tsc*_*cka 7

扩展杨的答案

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

<?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();
Run Code Online (Sandbox Code Playgroud)

输出:

一:1
:1
一:2
:3 <-- x_repeat
一:4
:5 <-- x_repeat
:2

http://ideone.com/W4W5Qv