资讯专栏INFORMATION COLUMN

PHP后期静态绑定分析与应用

red_bricks / 2469人阅读

摘要:用于调用父类中被覆盖的属性或方法出现在哪里,就将解析为相应类的父类。所以,可以用后期静态绑定的办法解决单例继承问题。

基础知识 1. 范围解析操作符 (::)

可以用于访问静态成员类常量,还可以用于覆盖类中的属性和方法

self,parent 和 static 这三个特殊的关键字是用于在类定义的内部对其属性或方法进行访问的。

parent用于调用父类中被覆盖的属性或方法(出现在哪里,就将解析为相应类的父类)。

self用于调用本类中的方法或属性(出现在哪里,就将解析为相应的类;注意与$this区别,$this指向当前实例化的对象)。

当一个子类覆盖其父类中的方法时,PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。

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

运行结果:

AA
AA

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

3.Static(静态)关键字

作用:

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

例子:

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


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

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

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

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

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

staticValue() . "
";
print $foo->my_static . "
";      // Undefined "Property" my_static 

print $foo::$my_static . "
";
$classname = "Foo";
print $classname::$my_static . "
"; // As of PHP 5.3.0

print Bar::$my_static . "
";
$bar = new Bar();
print $bar->fooStatic() . "
";
?>
-------------------------------------------->

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() . "
";
echo $apple->parentname() . "
";
echo $apple->staticname();

?>




运行结果:
Mango
Orange
Apple

b)使用forward_static_call()






运行结果:
Orange is
Orange is my favorite fruit
Apple is my father"s favorite fruit

c)使用get_called_class()





运行结果:
Mango
Orange
应用

前面已经提到过了,引入后期静态绑定的目的是:用于在继承范围内引用静态调用的类。
所以, 可以用后期静态绑定的办法解决单例继承问题。

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


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

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


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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28440.html

相关文章

  • PHP中staticyield关键字的思考

    摘要:先来说说关键字。什么时候用来修饰方法关键字大家都知道是用来修饰方法与属性的。一句话学会面向对象的方式来思考。充分发挥其性能优势,又能解决扩展性差的问题。这里不会进行与的比较。 你以为你知道了一切,只是你以为而已。知识的美妙就在于,一生的时光在它面前显得多么的短暂。 嗯嗯,扯远了,我今天只想说说:static 与 yield。 先来说说 static 关键字。本篇只讲静态方法的使用与后期...

    thursday 评论0 收藏0
  • 【Laravel】Laravel 框架关键技术解析·读书笔记(一)

    摘要:判断是否存在构造函数,不存在直接实例化,存在则通过来获取输入函数,并有相应的方法解决依赖参数问题,实现依赖注入。 Laravel 框架关键技术解析·读书笔记(一) 第一章 入口文件 请求访问的入口文件,主要完成几部分工作,分别是: 自动加载函数的添加 服务器实例化与服务注册 路由加载 请求实例化与路由分发 相应生成与发送 其中,自动加载函数用于包含引用文件,改文件是composer...

    CocoaChina 评论0 收藏0
  • php易错笔记-类对象,命名空间

    摘要:类与对象基本概念如果在之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个名字空间,则必须使用其完整名称。如果一个类被声明为,则不能被继承。命名空间通过关键字来声明。 类与对象 基本概念 new:如果在 new 之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个名字空间,则必须使用其完整名称。 Example #3 创建一个实例 ...

    MartinHan 评论0 收藏0
  • Laravel 中的一个后期静态绑定

    摘要:实验一个抽象类,有个方法,通过延迟静态绑定实例化并返回。这里如果把注释打开,打印的就是重写的值如果把抽象类改成普通类,改成的方式实例化,结果就不同了,打印的属性都是各自类的属性。 (原文地址,内容以原文为准,可能修改或者补充:https://blog.tanteng.me/2017/...) 关于 PHP 的 new static 延迟静态绑定,或者叫后期静态绑定,在 Laravel...

    30e8336b8229 评论0 收藏0
  • PHP中的后期绑定

    摘要:先看一个例子输出如果使用后期绑定后期静态绑定从这里开始输出使用或者对当前类的静态引用,取决于定义当前方法所在的类,而不是调用者所在的类。后期绑定的意思是说,不再被解析为定义当前方法所在的类,而是在实际运行时计算的。 先看一个例子: 输出: A 如果使用后期绑定: 输出: B 使用 self:: 或者 CLASS 对当前类的静态引用,取决于定义当前方法所在的类,而不是调用者所在...

    dadong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<