static关键字修饰函数内部变量、方法声明及类内部属性和方法;其变量生命周期绑定函数但作用域限于函数体,静态方法不可用$this,类中静态属性为所有实例共享。

PHP里的static关键字到底修饰谁?
它不修饰类,也不修饰整个文件,只作用于function内部的变量、方法声明,或class内部的属性和方法。最常混淆的是:把static $count = 0;当成“全局变量”,其实它生命周期绑定函数,作用域仍局限在函数体内——每次调用foo(),$count不会重置,但外部完全访问不到。
-
static变量只在首次执行到该行时初始化一次,后续调用跳过初始化 -
static方法不能用$this,也不能访问$this->prop或$this->method() - 类中
static $config属于类本身,所有实例共享同一份内存,不是每个对象一份
什么时候必须用static方法?
当逻辑与具体对象无关,又需要被类组织起来时——比如工具类、配置加载器、单例入口。典型例子:DateTime::createFromFormat()就是静态方法,你不需要先new DateTime再调它。
- 数据库连接工厂:
DB::connect(),避免每次实例化都新建连接 - 缓存读写封装:
Cache::get($key),底层可能用apcu_fetch,无需实例上下文 - 反模式警告:别为了“看起来高级”把所有工具函数都塞进
static,会加大测试难度(无法mock)
self、static、parent在静态上下文里怎么选?
这是新手掉坑最多的地方。三者都用于类内调用,但绑定时机不同:self编译期绑定,static运行期绑定(后期静态绑定),parent只指向直接父类。
class A {
public static function who() { echo __CLASS__; }
public static function test() { self::who(); } // 总是输出 'A'
public static function testLate() { static::who(); } // 子类调用时输出子类名
}
class B extends A {
public static function who() { echo __CLASS__; }
}
B::test(); // 输出 'A'
B::testLate(); // 输出 'B'
- 想严格锁定当前声明类 → 用
self - 想支持子类覆盖行为 → 用
static(尤其在工厂、构建器模式中) - 明确要调父类实现 → 用
parent::method(),且仅限继承链中直接上一级
静态属性被意外修改怎么办?
PHP不做访问控制默认放行,public static $data可被任意代码改写,连unset都拦不住。这不是bug,是语言设计选择——意味着你得主动防御。
立即学习“PHP免费学习笔记(深入)”;
- 敏感配置项一律设为
private static,提供public staticgetter(只读) - 数组类静态数据,用
array_merge或...$arr复制后再返回,避免外部直接改原数组 - 注意
clone不影响静态属性,但serialize/unserialize会保留其值,跨请求不生效(因为PHP每次请求重载类)
静态不是银弹,它让状态脱离对象生命周期,也放大了共享风险。真正难的不是写static,而是判断「这个状态到底该不该跨实例存在」。











