【发布时间】:2011-09-05 13:11:17
【问题描述】:
我正在查看 Drupal 7 的源代码,发现了一些我以前从未见过的东西。我在 php 手册中做了一些初步的查找,但没有解释这些示例。
关键字static 对函数内的变量有什么作用?
function module_load_all($bootstrap = FALSE) {
static $has_run = FALSE
【问题讨论】:
标签: php function static keyword
我正在查看 Drupal 7 的源代码,发现了一些我以前从未见过的东西。我在 php 手册中做了一些初步的查找,但没有解释这些示例。
关键字static 对函数内的变量有什么作用?
function module_load_all($bootstrap = FALSE) {
static $has_run = FALSE
【问题讨论】:
标签: php function static keyword
它使函数在多次调用之间记住给定变量的值(在您的示例中为$has_run)。
您可以将其用于不同的目的,例如:
function doStuff() {
static $cache = null;
if ($cache === null) {
$cache = '%heavy database stuff or something%';
}
// code using $cache
}
在这个例子中,if 只会被执行一次。即使会多次调用doStuff。
【讨论】:
$cache的值重置为null,对吧?
$cache 只会在请求之间重置。所以是的,它不会在以后调用同一请求(或执行脚本)时重置。
if条件检查$cache === null,而不是认为if的块代码$cache = '..'会被执行。
到目前为止,似乎没有人提到,同一类的不同实例中的静态变量保持其状态。所以写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
【讨论】:
举个例子:
function a($s){
static $v = 10;
echo $v;
$v = $s;
}
第一次调用
a(20);
将输出10,然后将$v 输出为20。变量$v 在函数结束后不会被垃圾回收,因为它是一个静态(非动态)变量。在脚本完全结束之前,该变量将保持在其范围内。
因此,下面的调用
a(15);
然后会输出20,然后将$v设置为15。
【讨论】:
静态的工作方式与在类中的工作方式相同。该变量在函数的所有实例之间共享。在您的特定示例中,一旦运行该函数, $has_run 将设置为 TRUE。该函数的所有未来运行都将具有 $has_run = TRUE。这在递归函数中特别有用(作为传递计数的替代方法)。
静态变量只存在于 局部函数作用域,但不是 程序执行时失去价值 离开这个范围。
【讨论】:
如果您使用静态变量扩展类,则各个扩展类将保存其“自己的”引用的静态变量,这些静态变量在实例之间共享。
<?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
【讨论】:
函数中的静态变量意味着无论你调用多少次函数,只有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 表示在页面加载期间每次调用函数时,该变量都会保留其值。
因此,在您给出的示例中,如果您调用一个函数两次,如果它将$has_run 设置为true,那么该函数将能够知道它以前被调用过,因为$has_run 仍然会函数第二次启动时等于true。
static 关键字在此上下文中的用法在此处的 PHP 手册中进行了说明:http://php.net/manual/en/language.variables.scope.php
【讨论】: