php 后期静态绑定 static 关键字的另一种用法

本文介绍了PHP 5.3.0引入的后期静态绑定功能,该功能允许在继承范围内引用静态调用的类,并详细解释了如何使用static关键字来调用类的静态方法和属性,同时对比了self关键字的不同之处。

自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类。 虽然也可以调用非静态方法,但是不会在运行时绑定。

static 不再只是简单的静态修饰关键字。而是可以像下面这样调用类的静态方法,非静态方法,为什么静态非静态要分开说呢,因为调用的效果是不一样的。

<?php
class  A  {
    public static function  who () {
        echo  __CLASS__ ;
    }
    public static function  test () {
        static:: who ();  // 后期静态绑定从这里开始
     }
}

class  B  extends  A  {
    public static function  who () {
        echo  __CLASS__ ;
    }
}

B :: test ();
?> 

如上代码:B调用test方法,test方法调用who方法。而B类中重写了who方法,则实际调用的是B中的who方法,所以输出的__CLASS__是B  这就是说 static 调用的静态方法会在运行时自动判断调用谁的方法。而self则只会调用定义它时所在的类中的方法。这是static的一个区别于其它调用的一个新特性。而static调用非静态方法时则不会达到这种后期绑定的效果,所以叫后期静态绑定。

还有就是 static只能调用静态属性。

总结:

综上所述,static关键字可以实现以下功能:

1 调用类的静态方法   有后期静态绑定效果;

2 调用类的静态属性   有后期静态绑定效果;

3 调用类的非静态方法  没有后期静态绑定效果;

4 强调一下 不可以调用非静态属性;


<think>好的,我现在需要帮助用户理解PHP中的后期静态绑定static::的用法和原理。首先,我得回忆一下自己对这个概念的理解,然后结合提供的引用资料来组织回答。 用户的问题是关于PHP后期静态绑定的,特别是static::的用法和原理。我需要确保回答结构清晰,分点解释,同时引用提供的参考资料来支持观点。 首先,我应该明确后期静态绑定的定义,可能要从self::和parent::的区别说起。根据引用[3]和[4],后期静态绑定允许static::在运行时确定类,而不是在定义时。这类似于非静态方法中的$this,但适用于静态调用。 接下来,用户可能需要一个基本用法的例子。引用[1]中的示例正好展示了static::和self::的不同行为。当B调用test()时,使用static::who()会调用B的who()方法,而如果使用self::who(),则调用A的who()。这说明static::会根据调用的类动态绑定。 然后,我需要解释其原理。根据引用[3],后期静态绑定在运行时解析,而self在编译时确定。这意味着static::会查找实际调用者的类,而self始终指向定义它的类。引用[4]提到static类似于$this,但用于静态上下文,这有助于用户理解其动态特性。 还要注意应用场景,比如在父类方法中调用子类的静态方法,或者实现静态工厂模式。引用[1]中的示例就是父类方法使用static::来允许子类覆盖。 最后,对比self、parent和static的区别,帮助用户明确各自的作用域和绑定时机。引用[2]中的例子显示self在父类中调用父类方法,而static则能正确指向子类。 在组织回答时,需要确保使用正确的LaTeX格式,如行内公式用$...$,独立公式用$$...$$。不过在这个问题中可能涉及较少数学表达式,但代码块需要用正确的格式呈现。 可能还需要生成相关问题,比如后期静态绑定与普通静态调用的区别,或者实际应用中的例子。这些问题应该围绕用户的问题展开,帮助深入理解。 检查引用是否正确标注,每个引用的末尾加上对应的标识符,如[^1]、[^2]等,确保用户能对应到提供的参考资料。 总结回答的结构应该是:定义、用法示例、原理解析、对比分析、应用场景、注意事项,最后相关问题。这样逐步深入,帮助用户逐步理解。</think>### PHP后期静态绑定 static:: 用法及原理解析 #### 一、核心定义 后期静态绑定(Late Static Binding)是PHP 5.3引入的特性,用于在继承链中动态解析静态方法/属性的调用类。`static::`会在运行时根据实际调用类确定目标,而`self::`和`parent::`在编译时固定绑定[^3][^4]。 #### 二、基础用法示例 ```php class A { public static function test() { static::who(); // 动态绑定到调用者类 } public static function who() { echo __CLASS__; } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); // 输出"B"[^1] ``` 若将`static::who()`改为`self::who()`,输出会变为"A"[^2],体现了两种关键字的差异。 #### 三、运行原理 1. **编译时与运行时绑定** `self::`在代码编写阶段确定目标类(定义该方法的类),`static::`则在方法调用时动态解析: $$ \text{static::} \Rightarrow \text{实际调用者类} $$ $$ \text{self::} \Rightarrow \text{定义方法的类} $$[^3] 2. **继承链穿透** 当子类未覆盖父类的静态方法时,`static::`会继续向父级查找,类似`$this`的非静态方法调用逻辑。 #### 四、对比分析 | 关键字 | 绑定时机 | 作用范围 | 典型场景 | |-------------|----------|----------------------|------------------------| | `self::` | 编译时 | 定义该方法的类 | 严格限定当前类的实现 | | `parent::` | 编译时 | 直接父类 | 调用父类原始实现 | | `static::` | 运行时 | 实际调用者的类 | 实现多态性静态方法 | #### 五、应用场景 1. **静态工厂模式** ```php abstract class Model { public static function create() { return new static(); // 根据调用类实例化对象 } } class User extends Model {} $user = User::create(); // 创建User实例 ``` 2. **模板方法模式** 父类定义算法骨架,子类通过`static::`实现具体步骤: ```php abstract class Report { public static function generate() { $data = static::fetchData(); // 子类实现数据获取 return static::format($data); } } ``` #### 六、注意事项 1. **非静态上下文** `static::`也可在非静态方法中使用,但此时`$this`仍指向对象实例 2. **性能影响** 动态解析会带来微小性能损耗,在超高频调用场景需评估
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梧桐深院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值