详解后期静态绑定在PHP中的使用

作者:神秘网友 发布时间:2021-02-28 14:44:52

详解后期静态绑定在PHP中的使用

什么叫后期静态绑定呢?其实我们在之前的文章PHP中的static中已经说过这个东西了。今天我们还是再次深入的理解一下这个概念。

推荐:《PHP视频教程》

首先,我们通过一段代码来引入后期静态绑定这一概念:

class A
{
    public static function who()
    {
        echo __CLASS__, PHP_EOL;
    }
    public static function test()
    {
        self::who();
    }
}

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

B::test(); // A

在这段代码中,我们使用了self关键字,当使用B类调用test()静态方法时,self指向的是A类的who()方法,因此,输出的是A。别激动,这是普通的静态绑定。self关键字调用的内容取决于它定义时所在的类。也就是说不管怎么继承,用哪个子类来调用test()方法,self关键字都会调用的是A类的who()方法。

而后期静态绑定呢?其实就有点像实例化的类对象,每个实例化的对象,调用的都是自身,而不是父类的属性方法。普通的静态调用可不是这样,但是现实中我们又有这样的需求,就像实例化对象的调用方式一样来调用静态属性方法,这时,我们就可以使用static关键字来实现后期静态绑定。

class C
{
    public static function who()
    {
        echo __CLASS__, PHP_EOL;
    }
    public static function test()
    {
        static::who();
    }
}

class D extends C
{
    public static function who()
    {
        echo __CLASS__, PHP_EOL;
    }
}

D::test(); // D

当使用static关键字后,这里D类调用的test()方法内部调用的who()就是D类自己了。

官方文档中的定义如下:

当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。

该功能从语言内部角度考虑被命名为“后期静态绑定”。“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。

除了self和static关键字外,我们还有一个parent关键字,这个关键字的意义就很明显了,调用父类的静态内容。我们同时用三个关键字一起来进行测试:

class E
{
    public static function who()
    {
        echo __CLASS__, PHP_EOL;
    }
    public static function test()
    {
        self::who();
        static::who();
    }
}

class F extends E
{
    public static function who()
    {
        echo __CLASS__, PHP_EOL;
    }
}

class G extends F
{
    public static function who()
    {
        parent::who();
        echo __CLASS__, PHP_EOL;
    }
}

G::test();

// E
// F
// G

最后,我们再来看两个PHP的方法,一个是get_called_class()方法,用来获取当前调用的是哪个类。在静态方法中可以根据调用方式判断当前类是哪个类来进行其他的业务逻辑操作。另一个是forward_static_call()方法,用于静态方法的调用。

class H
{
    public static function who()
    {
        echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL;
    }
    public static function test()
    {
        echo get_called_class(), PHP_EOL;
        forward_static_call('who', 'a', 'b'); // xxx:a,b
        forward_static_call(['I', 'who'], 'c', 'd'); // I:c,d
        forward_static_call_array(['H', 'who'], ['e', 'f']); // H:e,f
    }
}

class I extends H
{
    public static function who()
    {
        echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL;
    }
}

function who()
{
    echo 'xxx:' . join(',', func_get_args()), PHP_EOL;
}

H::test(); // H
// xxx:a,b
// I:c,d
// H:e,f
I::test(); // I
// xxx:a,b
// I:c,d
// H:e,f

注意,如果forward_static_call()不指定类名的话,将调用全局的方法。forward_static_call_array()则是将参数使用数组进行传递。

测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202001/source/%E5%90%8E%E6%9C%9F%E9%9D%99%E6%80%81%E7%BB%91%E5%AE%9A%E5%9C%A8PHP%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8.php

详解后期静态绑定在PHP中的使用的教程已介绍完毕,更多请关注跳墙网其他文章教程!

详解后期静态绑定在PHP中的使用 相关文章

  1. 详解phpMyAdmin配置连接远程数据库

    下面由 phpmyadmin 教程栏目给大家介绍phpMyAdmin怎么配置连接远程数据库,希望对需要的朋友有所帮助! phpMyAdmin配置连接远程数据库 背景 wampserver 3.1.7、Apache 2.4.37、PHP 7.2.14、MySql 5.7.24、thinkcmf 5.0 配置 wampserver安装目录下搜索config.i

  2. 详解golang.org/x一键安装脚本

    下面由 golang 教程栏目给大家介绍golang.org/x一键安装脚本,希望对需要的朋友有所帮助! golang.org/x一键安装脚本 背景 由于各种问题,国内使用 go get 安装 golang 官方包可能会失败,如我自己在安装 collidermain 时,出现了以下报错: $ go get collide

  3. NetCore项目在Linux中使用Supervisor托管详解

    本文实例环境及版本 Centos7 、NetCore 3.1、Supervisor 4.2.1前置条件需安装好NetCore的SDK等,网上有相关实例也可以转到我整理的文档 https://www.cnblogs.com/mzflog/p/14456929.html Supervisor简介 Supervisor官网地址:http://supervisord.org/源码位置

  4. 通过子类引用父类的静态字段,不会导致子类初始化

    Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程 和那些编译时需要连接工作的语言不同,在Java语言里,类型的加载,连接和初始化过程都是在程序 运行期间

  5. 题解 小p的新牧场 详解斜率优化

    题面 背景 小 P 是个特么喜欢玩 MC 的孩纸。。。 描述 小 P 在 MC 里有 n 个牧场,自西向东呈一字形排列(自西向东用 1…n 编号),于是 他就烦恼了:为了控制这 n 个牧场,他需要在某些牧场上面建立控制站,每个牧场 上只 能建立一个控制站,每个控制站控制

  6. Java中static

    static 1.静态/非静态变量 eg: private static int age; // 静态变量private double score; //非静态变量 在调用age时,直接通过 类名.age 即可访问; 而score 必须通过创建对象来调用。 2.静态/非静态方法 eg: //非静态方法public void run(){}//静态方法pu

  7. Nginx配置详解-copy

    Nginx配置详解 Nginx实现前后端分离,反向代理、负载均衡 配置详解: #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数。 worker_processes 8; #全局错误日志定义类型,[ debug | info | notice | warn | error | crit

  8. android 加载assets目录下的静态html文件案例

    1、添加assets目录 在main目录下添加assets目录,如下: 2、再在assets目录添加一个web目录,如下: 3、webview加载assets目录下html静态文件,代码如下: String url = "file:///android_asset/web/index.html"; webView.loadUrl(url); ps: 路径是 "file:/

  9. Python计数器collections.Counter用法详解

    介绍: Python collections.Counter用法详解,Counter 计数器,顾名思义就是用来计数的,最主要的作用就是计算“可迭代序列中”各个元素(element)的数量。具体用法参看目录,基本涵盖了主要用法。 01.统计“可迭代序列”中每个元素的出现的次数 #首先引入

  10. Java集合框架详解

    Java集合框架详解 集合的概念 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能 和数组区别: (1)数组长度固定,集合长度不固定 (2)数组可以存储基本类型和引用类型,集合只能存储引用类型 位置:Java.util.* Collection体系 ![

每天更新java,php,javaScript,go,python,nodejs,vue,android,mysql等相关技术教程,教程由网友分享而来,欢迎大家分享IT技术教程到本站,帮助自己同时也帮助他人!

Copyright 2020, All Rights Reserved. Powered by 跳墙网(www.tqwba.com)|网站地图|关键词