【问题标题】:`static` keyword inside function?函数内部的`static`关键字?
【发布时间】:2011-09-05 13:11:17
【问题描述】:

我正在查看 Drupal 7 的源代码,发现了一些我以前从未见过的东西。我在 php 手册中做了一些初步的查找,但没有解释这些示例。

关键字static 对函数内的变量有什么作用?

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

【问题讨论】:

标签: php function static keyword


【解决方案1】:

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

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

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

在这个例子中,if 只会被执行一次。即使会多次调用doStuff

【讨论】:

  • 另外,如果函数已经运行过一次,它不会在以后的调用中将$cache的值重置为null,对吧?
  • @user151841 $cache 只会在请求之间重置。所以是的,它不会在以后调用同一请求(或执行脚本)时重置
  • @Muhammad 因为这正是关键字 static 所做的。
  • 我相信每次调用这个函数时都会执行if条件检查$cache === null,而不是认为if的块代码$cache = '..'会被执行。
  • 如果函数是类中的方法会发生什么,静态变量是否在实例之间共享?
【解决方案2】:

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

【讨论】:

  • 哎哟!这不止一次地咬了我。我希望静态只适用于实例,提供记忆;但这是错误的思维方式,因为类上下文中的“静态”意味着整个类。属性、方法和变量。
【解决方案3】:

举个例子:

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

第一次调用

a(20);

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

因此,下面的调用

a(15);

然后会输出20,然后将$v设置为15

【讨论】:

    【解决方案4】:

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

    静态变量只存在于 局部函数作用域,但不是 程序执行时失去价值 离开这个范围。

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

    【讨论】:

      【解决方案5】:

      扩展the answer of Yang

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

      <?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 一:4
      :5 :2

      http://ideone.com/W4W5Qv

      【讨论】:

        【解决方案6】:

        函数中的静态变量意味着无论你调用多少次函数,只有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
        
        ?>
        

        【讨论】:

          【解决方案7】:

          在函数内部,static 表示在页面加载期间每次调用函数时,该变量都会保留其值。

          因此,在您给出的示例中,如果您调用一个函数两次,如果它将$has_run 设置为true,那么该函数将能够知道它以前被调用过,因为$has_run 仍然会函数第二次启动时等于true

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-23
            • 2022-07-21
            • 2012-12-30
            • 1970-01-01
            相关资源
            最近更新 更多