php中的延迟静态绑定功能(使用static等关键字)

本文中的PHP版本:PHP Version 7.2.5


从文章中的标题名字的定义提取出两个关键点,第一点静态,也就是说这个功能只适用于静态属性或静态方法。第二点延迟绑定。


类可以自下往上调用父类方法,如果需要在父类中根据不同的子类,来调用子类的方法,那么就需要延迟静态绑定。延迟静态绑定用的是保留关键词static


所谓延迟静态绑定,顾名思义,静态调用时::符号左侧的部分的的绑定是延迟,也就是说不再被解析为定义当前方法所在的类,而是在实际运行时计算的


话不多说 直接上代码:

class People
{

    public static function hungry()
    {
        static::eat(); //static和调用它的类进行静态绑定,然后调用static所绑定的类 的eat方法
    }

    public static function eat()
    {
        echo __CLASS__." is eat";
    }
}

class Zack extends People
{

    public static function hungry()
    {
        parent::hungry();
    }

    public static function eat()
    {
        echo __CLASS__." is eat \n";
    }
}

class Duke extends People
{

    public static function hungry()
    {
        parent::hungry();
    }

    public static function eat()
    {
        echo __CLASS__." is eat \n";
    }
}


/**
 代码执行流程
 运行代码之后 先执行Zack::hungry()方法 然后这个方法里面又去调用了父类的hungry()方法 然后父类的hungry()方法内部发现是一个static延迟调用 因为此时调用者是Zack类
 所以父类hungry()方法里面的static::eat() 就会去调用Zack::eat()
 通俗来说 在这段代码中 父类hungry()方法里面的static::eat() 就等于Zack::eat()
 */
Zack::hungry(); //输出:Zack is eat



/**
代码执行流程
运行代码之后 先执行Duke::hungry()方法 然后这个方法里面又去调用了父类的hungry()方法 然后父类的hungry()方法内部发现是一个static延迟调用 因为此时调用者是Duke类
所以父类hungry()方法里面的static::eat() 就会去调用Duke::eat()
通俗来说 在这段代码中 父类hungry()方法里面的static::eat() 就等于Duke::eat()
 */
Duke::hungry(); //输出:Duke is eat

如果将上面代码中的第5行的static::eat();换成self::eat();  运行就是绑定的当前方法所在的类,而不是静态调用的类。最终输出的结果如下:

People is eat 
People is eat 


注意:只有在使用以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()和forward_static_call_array()时才会进行转发调用。转发调用即将当前的调用者传递给后面调用的方法。


以官网的实例来解释一下:

class A
{
    public static function foo()
    {
        static::who();
    }

    public static function who()
    {
        echo __CLASS__."<br/>";
    }
}

class B extends A
{
    public static function test()
    {
        //通过类名进行调用,是非转发调用,调用者是A
        A::foo();

        //parent和self均是转发调用,将调用者C进行转发,所以调用者还是C
        parent::foo();
        self::foo();
    }

    public static function who()
    {
        echo __CLASS__."<br/>";
    }
}

class C extends B
{
    public static function who()
    {
        echo __CLASS__."<br/>";
    }
}

C::test();

通过self::,parent::,static:: 以及 forward_static_call()和forward_static_call_array()调用时,调用者会被继续转发。故以上代码运行之后会输出:

A
C
C



可以在项目中自行挖掘使用场景,比如一个会员父类  class Vip

下面两个子类分别是 超级会员 svip 和 年费会员 yvip

可以在两个子类中分别重写 static usergroup() 方法 或者其他静态属性 ,父类中使用延迟静态绑定

这样可以写出很优雅的代码



无论从事什么行业,只要做好两件事就够了,一个是你的专业、一个是你的人品,专业决定了你的存在,人品决定了你的人脉,剩下的就是坚持,用善良专业和真诚赢取更多的信任。



声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

小周博客
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复 0人评论 7,777人参与

loading