php静态变量在函数首次调用时初始化并保留后续调用的值,作用域限于函数内部,支持闭包和类型声明,适用于单请求内记忆化但需警惕内存累积、配置缓存失效及测试难重置等问题。

静态变量能记住上一次函数执行的值
PHP 的 static 变量只在函数第一次调用时初始化,之后每次调用都保留上次结束时的值。这不是全局变量,也不靠外部传参,而是函数内部“自带记忆”。适合需要状态延续但又不想污染全局作用域的场景。
常见错误现象:static $count = 0; 写成 $count = 0;,结果每次调用都重置;或者误以为 static 能跨多个函数共享(它不能,每个函数的 static 是独立的)。
- 只在函数作用域内有效,类方法里也支持
- 初始化表达式仅执行一次,哪怕写的是
static $x = time();,值也是首次调用时的时间戳 - 不能用动态表达式初始化(如
static $arr = [$_SERVER['HTTP_HOST']];会报错)
递归函数里用 static 避免重复计算
比如斐波那契或树遍历中缓存中间结果,static 可以当轻量级记忆化容器,比全局数组更收敛、比参数传递更干净。
使用场景:单次请求内多次调用同一函数,且输入固定、输出可复用。
立即学习“PHP免费学习笔记(深入)”;
性能影响:省去重复运算,但要注意内存不释放——如果缓存键过多或值过大,可能累积占用内存。
示例:
function fib($n) {
static $cache = [];
if (isset($cache[$n])) return $cache[$n];
if ($n < 2) return $n;
$cache[$n] = fib($n - 1) + fib($n - 2);
return $cache[$n];
}static 变量不是线程安全的,别在 CLI 多进程里乱用
PHP-FPM 或 Apache 模式下,每个请求是独立进程/线程,static 变量互不影响;但在 CLI 下启多进程(如 pcntl_fork()),子进程会复制父进程的内存,包括 static 值,后续修改彼此隔离——看起来像“共享”,实则只是初始值相同,容易误判。
兼容性注意点:
- PHP 5.6+ 支持在闭包里用
static(需显式声明,如static $i = 0;) - PHP 7.4+ 允许对
static变量做类型声明(如static int $counter = 0;) - 不支持在类属性上直接用
static(那是static属性,语法和语义都不同)
和 global / $GLOBALS 比,static 更安全也更受限
static 不会污染全局命名空间,也不能被函数外读写,天然防误改。但它也意味着没法从外部重置或调试——比如单元测试时想清空缓存,就得在函数内部暴露一个清理逻辑。
容易踩的坑:
- 把
static $config = parse_ini_file('a.ini');当配置缓存,结果文件更新后不生效(因为只加载一次) - 在循环里反复调用含
static的函数,却忘了它的值会持续累加,导致逻辑错位 - 在 include 文件中定义带
static的函数,又被多次 include,不会重复初始化,但容易让人误以为“每次引入都重来”
真正难处理的,是那些隐式依赖 static 状态的函数——它们表面无副作用,实际有内部状态,调用顺序和次数都会影响结果。这种耦合藏得深,改起来比全局变量还费劲。











