函数内的“static”关键字?

发布于 2024-11-11 18:16:14 字数 219 浏览 3 评论 0原文

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

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

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

I was looking at the source for Drupal 7, and I found some things I hadn't seen before. I did some initial looking in the php manual, but it didn't explain these examples.

What does the keyword static do to a variable inside a function?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

沫离伤花 2024-11-18 18:16:14

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

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

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

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

It makes the function remember the value of the given variable ($has_run in your example) between multiple calls.

You could use this for different purposes, for example:

function doStuff() {
  static $cache = null;

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

  // code using $cache
}

In this example, the if would only be executed once. Even if multiple calls to doStuff would occur.

我的鱼塘能养鲲 2024-11-18 18:16:14

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

Seems like nobody mentioned so far, that static variables inside different instances of the same class remain their state. So be careful when writing OOP code.

Consider this:

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

If you want a static variable to remember its state only for current class instance, you'd better stick to a class property, like this:

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
闻呓 2024-11-18 18:16:14

给出以下示例:

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

第一次调用

a(20);

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

因此,下面的调用

a(15);

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

Given the following example:

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

First call of

a(20);

will output 10, then $v to be 20. The variable $v is not garbage collected after the function ends, as it is a static (non-dynamic) variable. The variable will stay within its scope until the script totally ends.

Therefore, the following call of

a(15);

will then output 20, and then set $v to be 15.

剧终人散尽 2024-11-18 18:16:14

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

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

请参阅http://php.net/manual/en/language.variables.scope。 php

Static works the same way as it does in a class. The variable is shared across all instances of a function. In your particular example, once the function is run, $has_run is set to TRUE. All future runs of the function will have $has_run = TRUE. This is particularly useful in recursive functions (as an alternative to passing the count).

A static variable exists only in a
local function scope, but it does not
lose its value when program execution
leaves this scope.

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

笑忘罢 2024-11-18 18:16:14

要扩展 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 <-- x_repeat
一:4
:5 <-- x_repeat
两个:2

http://ideone.com/W4W5Qv


其他信息由 @保罗·安德鲁斯
需要注意,从 PHP8.1 开始,情况不再如此。您现在将得到输出:

一:1,
二:2,
一:3,
一:4,
一:5,
一:6,
二:7。

php.net/manual/en/language.variables.scope 中提到了这一点。 php

从 PHP 8.1.0 开始,当继承使用静态变量的方法时
(但不被覆盖),继承的方法现在将共享静态
父方法的变量。

To expand on the answer of Yang

If you extend a class with static variables, the individual extended classes will hold their "own" referenced static that's shared between instances.

<?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();

outputs:

one:1
two:1
one:2
one:3 <-- x_repeat
one:4
one:5 <-- x_repeat
two:2

http://ideone.com/W4W5Qv


Additional info by @Paul Andrews
To note, as of PHP8.1 this is no longer true. You will now get the output:

one:1,
two:2,
one:3,
one:4,
one:5,
one:6,
two:7.

This is mentioned on php.net/manual/en/language.variables.scope.php :

As of PHP 8.1.0, when a method using static variables is inherited
(but not overridden), the inherited method will now share static
variables with the parent method.

情话墙 2024-11-18 18:16:14

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

?>

static variable in a function means that no matter how many times you call the function, there's only 1 variable.

<?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

?>
万劫不复 2024-11-18 18:16:14

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

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

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

Inside a function, static means that the variable will retain its value each time the function is called during the life of the page load.

Therefore in the example you've given, if you call a function twice, if it set $has_run to true, then the function would be able to know that it had previously been called because $has_run would still be equal to true when the function starts the second time.

The usage of the static keyword in this context is explained in the PHP manual here: http://php.net/manual/en/language.variables.scope.php

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文