“静态”关键字的内部功能?

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

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

function module_load_all($bootstrap = FALSE) {
static $has_run = FALSE
66454 次浏览

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

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

function doStuff() {
static $cache = null;


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


// code using $cache
}

在这个例子中,if只执行一次,即使对 doStuff的多次调用也是如此。

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

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

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

举例如下:

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

First call of

a(20);

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

因此,以下调用

a(15);

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

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

A static variable exists only in a 局部函数作用域,但它没有 程序执行时失去其价值 离开这个范围。

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

函数中的静态变量意味着无论调用函数多少次,只有一个变量。

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


?>

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.

想想这个:

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 属性,比如:

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

杨的回答上展开

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

<?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
one:2
one:3 <-- x_repeat
one:4
1 : 5 < —— x _ repeat
两个 : 2

Http://ideone.com/w4w5qv