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
也会发生.
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)
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
,然后$v
是20
.$v
函数结束后,变量不会被垃圾收集,因为它是一个静态(非动态)变量.变量将保持在其范围内,直到脚本完全结束.
因此,以下调用
a(15);
Run Code Online (Sandbox Code Playgroud)
然后输出20
,然后设置$v
为15
.
Static的工作方式与在类中的工作方式相同.该变量在函数的所有实例中共享.在您的特定示例中,一旦运行该函数,$ has_run将设置为TRUE.该函数的所有未来运行都将具有$ has_run = TRUE.这在递归函数中特别有用(作为传递计数的替代方法).
静态变量仅存在于本地函数作用域中,但在程序执行离开此作用域时它不会丢失其值.
见http://php.net/manual/en/language.variables.scope.php
扩展杨的答案
如果您使用静态变量扩展一个类,则各个扩展类将保留在实例之间共享的“自己的”引用静态。
<?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