博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP后期静态绑定分析与应用
阅读量:6106 次
发布时间:2019-06-21

本文共 2181 字,大约阅读时间需要 7 分钟。

基础知识

1. 范围解析操作符 (::)

  • 可以用于访问静态成员类常量,还可以用于覆盖类中的属性和方法
  • self,parent 和 static 这三个特殊的关键字是用于在类定义的内部对其属性或方法进行访问的。
  • parent用于调用父类中被覆盖的属性或方法(出现在哪里,就将解析为相应类的父类)。
  • self用于调用本类中的方法或属性(出现在哪里,就将解析为相应的类;注意与$this区别,$this指向当前实例化的对象)。
  • 当一个子类覆盖其父类中的方法时,PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。

2. PHP内核将类的继承实现放在了"编译阶段"

运行结果:

AAAA

结论:

self::和parent::出现在某个类X的定义中,则将被解析为相应的类X,除非在子类中覆盖父类的方法。

3.Static(静态)关键字

作用:

- 在函数体内的修饰变量的static关键字用于定义静态局部变量。- 用于修饰类成员函数和成员变量时用于声明静态成员。- (PHP5.3之后)在作用域解析符(::)前又表示静态延迟绑定的特殊类。

例子:

  1. 定义静态局部变量(出现位置:局部函数中)

    特征:静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。

  2. 定义静态方法,静态属性

    a)声明类属性或方法为静态,就可以不实例化类而直接访问。
    b)静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)
    c)如果没有指定访问控制,属性和方法默认为公有。
    d)由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
    e)静态属性不可以由对象通过 -> 操作符来访问。
    f)用静态方式调用一个非静态方法会导致一个 E_STRICT 级别的错误。
    g)就像其它所有的 PHP 静态变量一样,静态属性只能被初始化为文字或常量,不能使用表达式。所以可以把静态属性初始化为整数或数组,但不能初始化为另一个变量或函数返回值,也不能指向一个对象。

    -------------------------------------------->

    a.静态方法例子(出现位置: 类的方法定义)

    -------------------------------------------->

    b.静态属性例子(出现位置:类的属性定义)

    staticValue() . "\n";print $foo->my_static . "\n"; // Undefined "Property" my_static print $foo::$my_static . "\n";$classname = 'Foo';print $classname::$my_static . "\n"; // As of PHP 5.3.0print Bar::$my_static . "\n";$bar = new Bar();print $bar->fooStatic() . "\n";?>
    -------------------------------------------->

    c.用于后期静态绑定(出现位置: 类的方法中,用于修饰变量或方法)

    下面详细分析

后期静态绑定(late static binding)

自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类。

1.转发调用与非转发调用

转发调用 :

  • 指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。

非转发调用 :

  • 明确指定类名的静态调用(例如Foo::foo())
  • 非静态调用(例如$foo->foo())

2.后期静态绑定工作原理

原理:存储了在上一个“非转发调用”(non-forwarding call)中的类名。意思是当我们调用一个转发调用的静态调用时,实际调用的类是上一个非转发调用的类。

例子分析:

3.更多静态后期静态绑定的例子

a)Self, Parent 和 Static的对比

selfname() . "\n";echo $apple->parentname() . "\n";echo $apple->staticname();?>运行结果:MangoOrangeApple

b)使用forward_static_call()

运行结果:Orange isOrange is my favorite fruitApple is my father's favorite fruit

c)使用get_called_class()

运行结果:MangoOrange

应用

前面已经提到过了,引入后期静态绑定的目的是:用于在继承范围内引用静态调用的类。

所以, 可以用后期静态绑定的办法解决单例继承问题。

先看一下使用self是一个什么样的情况:

通过上面的例子可以看到,使用self,实例化得到的都是类A的同一个对象

再来看看使用static会得到什么样的结果

可以看到,使用static可以解决self时出现的单例继承问题。

转载地址:http://pieza.baihongyu.com/

你可能感兴趣的文章
Retrofit 源码剖析-深入
查看>>
企业级负载平衡简介(转)
查看>>
ICCV2017 论文浏览记录
查看>>
科技巨头的交通争夺战
查看>>
当中兴安卓手机遇上农行音频通用K宝 -- 卡在“正在通讯”,一直加载中
查看>>
Shell基础之-正则表达式
查看>>
JavaScript异步之Generator、async、await
查看>>
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>
直播视频流技术名词
查看>>
网易跟贴这么火,背后的某个力量不可忽视
查看>>
企业级java springboot b2bc商城系统开源源码二次开发-hystrix参数详解(八)
查看>>
java B2B2C 多租户电子商城系统- 整合企业架构的技术点
查看>>
IOC —— AOP
查看>>
比特币现金将出新招,推动比特币现金使用
查看>>
数据库的这些性能优化,你做了吗?
查看>>
某大型网站迁移总结(完结)
查看>>
mysql的innodb中事务日志(redo log)ib_logfile
查看>>
部署SSL证书后,网页内容造成页面错误提示的处理办法
查看>>
MS SQLSERVER通用存储过程分页
查看>>