php延迟静态绑定

PHP静态延迟绑定:用法解析与示例代码 在理解静态延迟绑定之前,我们先来了解一下PHP中的继承和静态成员。继承是面向对象编程中的一个重要概念,它允许我们创建一个新类,该类继承了父类的属性和方法。静态成员是属于类本身而不是类的实例的属性和方法。这意味着无论我们创建多少个类的实例,静态成员只存在于类本身。静态绑定是指在编译时将静态方法和属性绑定到类。这意味着无论我们通过哪个类的实例去调用静态方法或访问静态属性,都会使用编译时绑定的类。然而,有时我们希望能够在运行时动态地将静态方法和属性绑定到子类,这就是静态延迟绑定的作用。 阅读详情

问题背景

某天。新来的小A问了我一个问题 :子类重载了父类的方法,父类如何调用呢?

案例


<?php
class base{

}
class aClass extends base{
    public static function create(){
        return new aClass();
    }
}
class bClass extends base{
    public static function create(){
        return new bClass();
    }
}
var_dump(aClass::create());//object(aClass)#1 (0) { }
var_dump(bClass::create());//object(bClass)#1 (0) { }

?>

遵循面向对象的思想,子类重复的代码应该放在父类中实现,于是改进后:

<?php

class base{
    public static function create(){
        return new self();
    }
}
class aClass extends base{

}
class bClass extends base{

}
var_dump(aClass::create());
var_dump(bClass::create());

输出:
object(base)#1 (0) { }
object(base)#1 (0) { }

?>

显然,改进后的代码没有如我们所料。
原来父类中的self被解析为base这个父类,而不是解析成它的子类。
为了解决这个问题,php5.3引入了延迟静态绑定

延迟静态绑定

针对以上案例做改变:

<?php
class base{
    public static function create(){
        return new static();
    }
}
class aClass extends base{

}
class bClass extends base{

}
var_dump(aClass::create());//object(aClass)#1 (0) { } 
var_dump(bClass::create());//object(bClass)#1 (0) { }
?>

有意思的案例

<?php

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

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

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        echo __CLASS__."\n";
    }
}
class C extends B {
    public static function who() {
        echo __CLASS__."\n";
    }
}

C::test();
?>


输出:
A
C
C

A::foo()得到的结果是毫无疑问的,但是parent::foo()和self::foo()得到的结果就有点匪夷所思了。
而官方也只给出一句解释而已:
后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,如果静态调用使用 parent:: 或者 self:: 将转发调用信息。

看起来不知所云,于是我做了一些测试来理解:
首先,parent:: 和 self::各自解析为什么?
我把test()方法改了一下,让他们去调用自己的who()方法:

class B extends A {
    public static function test() {
        parent::who();//result:A
        self::who();//result:B
    }
}

parent::和self::是属于静态绑定,在编译期就确定了解析对象是谁。如self::就解析为自身B,而parent::就解析为自身的父类A。
而static::可以理解为是一种动态绑定,即在编译期无法确定解析对象是谁,只有到运行期才计算出解析的对象是谁。

按照以上的说法,A::foo()和B::foo()也不能得到C的结果?
这就得重新翻翻手册:

1.后期静态绑定本想通过引入一个新的关键字表示运行时最初调用的类来绕过限制。最终决定不引入新的关键字,而是使用已经预留的 static 关键字。
2.如果静态调用使用 parent:: 或者 self:: 将转发调用信息。

也就是说静态调用使用parent::或者self::时,他们会附带一个信息来告诉static::说,运行时最初调用的类是C,这也就是转发调用(转发最初调用者的信息)

验证方法:可以用get_called_class()来检查最初调用的类是谁?
修改后代码如下:

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

    public static function who() {
        var_dump(get_called_class());
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

    public static function who() {
        var_dump(get_called_class());
    }
}
class C extends B {
    public static function who() {
        var_dump(get_called_class());
    }
}

C::test();
?>



运行结果:

string(1) "A" 
string(1) "C" 
string(1) "C"

在这里还有一个疑问:如果C类里没有who()方法,那static::会解析成谁?

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

    public static function who() {
        echo __CLASS__;
    }
}

class B extends A {
    public static function test() {
        A::foo();
        parent::foo();
        self::foo();
    }

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

}

C::test();
?>

运行结果:

A
B
B

我们看看原先的官方解释:

后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。

也就是说,虽然运行期static::得到最初调用的类来自C,但是C中并没有who()方法,于是就去找C的父类B,B有who()方法,所以static::就解析为B

请关注我的订阅号

订阅号.png

共享单车需求预测问题:建模篇 机器学习训练营——机器学习爱好者的自由交流空间(qq群号:696721295) 在上一篇里,我们使用可视化的方法分析了“共享单车”的数据集,理解了特征(变量)之间的关系。我们将在本篇建立几个模型预测单车的需求量,并比较它们的预测效果。 随机森林填充法 首先,导入必需的库、训练集和检验集。 import pylab import calendar import numpy as np impor... 阅读详情

相关推荐

SAP CEWB 高效批量调整工艺路线与BOM的实战指南

本文详细介绍了SAP CEWB工具在批量调整工艺路线与BOM中的高效应用。通过实战案例和操作指南,帮助制造业企业快速掌握批量修改技巧,显著提升工作效率,避免手工操作带来的错误和耗时。特别适合需要频繁更新工艺路线和BOM的企业用户。

weixin_42524708的博客 397

PHP的延迟静态绑定

今天看一个接口不通的时候看到了在封装一个底层的model的时候,同事用到了 延迟静态绑定,虽然很奇怪,但是重点不在这,我们来将一个说一下这些概念性的东西。关键字实现了一种延迟静态绑定的机制,它允许在子类中覆盖静态方法并在运行时根据实际调用的类确定要调用的方法。关键字实现的延迟静态绑定的机制,它允许在子类中覆盖静态方法并在运行时根据实际调用的类确定要调用的方法。:对于实例方法,PHP 使用动态绑定,也就是在运行时根据实例的类来确定应该调用的方法。::不再被解析为当前方法所定义的类,而是在实际运行时计算的。

wqzbxh的博客 684

RLC电阻电容电感基础知识——电感篇

电感 等效电路 电感线圈由铜导线绕制,等效电路如图所示。 寄生电阻RS,包括了绕线电阻、引脚串联电阻以及磁芯损耗电阻三部分组成,其中绕线电阻与线径、长度、铜线电阻率有关;引脚电阻与引线长短、粗细有关;磁芯损耗电阻与磁芯材料特性有关,显然磁芯损耗电阻还与工作频率有关.寄生电容C主要是绕线圈与圈之间的杂散电容(为PF级),与绕线工艺有关。 等效导纳 显然: (1)当角频率ω(频率f)较小时,呈电感性. (2)当角频率ω等于ω0时,导纳Y虚部为0,呈现电阻性,即发生共振。令导纳Y虚部为0,即可求出共振角频率ω

azj2019的博客 1万+

php中延迟绑定,PHP静态延迟绑定

静态延迟绑定的概念PHP版本5.3起增加了静态延迟绑定,也称迟绑定,主要用于在继承范围内引用静态调用的类。简单地来说:static::不再被解析为当前方法所定义的类,而是在实际运行时计算的。// 意外的继承class Person{public static $name = 'Person';public static function say(){return self::$name;}}cla...

weixin_35213963的博客 352

深度学习之常用算子介绍

打开 onnx 模型图,可以看到它是一个有向无环图。除了 Input、Output ,其他都是算子(是操作,而不是节点)在ONNX(Open Neural Network Exchange)模型中,除了输入和输出,其他都是算子(Operations)。算子是表示神经网络模型中的不同操作或层的元素。一个ONNX模型由一系列算子组成,通过连接这些算子来定义模型的计算流程。

ueke1的博客 8459

CAPL自动化测试

通过本文的学习,读者应该对CAPL自动化测试有了初步的了解,并能够编写复杂的CAPL脚本。在实际项目中,CAPL的应用非常广泛,希望读者能够通过不断的学习和实践,掌握更多的CAPL技巧,提高自己的开发能力。

闲人编程的博客 1526

php中“延迟静态绑定”的使用

PHP的继承模型中有一个存在已久的问题,那就是在父类中引用扩展类的最终状态比较困难。我们来看一下代码清单5-11中的例子。 代码清单5-11 意想不到的继承  1 php  2   3 class ParentBase {  4   5   static $property = 'Parent Value';  6   7   public static function 

Lankecms 607

环境仿真软件:EcoPath with Ecosim_(4).Ecosim模型动态模拟

Ecosim 是 EcoPath with Ecosim (EwE) 软件中的动态模拟模块,用于模拟生态系统中各个组分的动态变化过程。Ecosim 模型通过时间序列数据和动态参数,可以预测生态系统在不同管理措施下的响应。时间序列数据的输入:用户可以输入历史数据,如捕捞努力、生物量、环境因子等,用于校准模型。动态参数的设置:用户可以设置被捕食率、生长率、捕捞死亡率等动态参数,以反映生态系统的变化。模拟结果的分析。

kkchenjj的博客 891

PHP延迟静态绑定

可以看到,在MySQLHandler和MemcachedHandler类中,都有一个create函数,除掉我的输出语句,发现它们一模一样,这就是代码冗余。所以,这就很好的解释了为什么上面的代码输出了A。代码重构无处不在,只要你想,你觉的有改进,就需要敲起键盘开始干活。这说明,并没有调用MySQLHandler的get函数,但是代码明明调用了啊,这说明,这种使用后期静态绑定,在使用PHP实现23中设计模式的时候,你会感到很轻松的。上面的代码输出了A,但是我希望它输出B,这就是问题的所在。

2301_77162959的博客 155

UDS诊断服务基础详解之七-31服务

本节内容主要是讲解诊断服务中的31服务,包含31服务的使用场景,请求报文格式,响应报文格式,以及举例对31服务进行相关的说明

车载网络小D的博客 5625

前后端面试题【目录】

工作时候扭螺丝,面试时候造火箭,现状就是如此。不管是背八股文,还是掌握了知识的精华,对答如流才是硬道理。本专栏就是要集具前端精华,规范、算法、架构、封装、原理等一并汇集,让前端的小伙伴有个思路。, 欢迎一起交流,并非常期望您能够提供有价值的学习资料。

大剑师兰特的GIS世界 1832

PHP延迟静态绑定的深入讲解

所以,这就很好的解释了为什么上面的代码输出了A。所谓延迟静态绑定,顾名思义,静态调用时::符号左侧的部分的的绑定是延迟,也就是说不再被解析为定义当前方法所在的类,而是在实际运行时计算的。可以看到,在MySQLHandler和MemcachedHandler类中,都有一个create函数,除掉我的输出语句,发现它们一模一样,这就是代码冗余。如果大家有什么建议,让我的文章写的更好,尽管提出来,我需要大家的帮助。好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值。

很酷的站长的博客 483

Python爬虫教程:抓取社交媒体内容(以Facebook和Instagram为例)

为什么抓取社交媒体内容?品牌分析与监测:通过抓取品牌、产品或服务相关的社交媒体数据,可以获得公众对其的评价,识别市场趋势,制定营销策略。情感分析:分析用户在社交平台上的情感倾向,如对某事件、产品、服务的正面或负面情绪。舆情监控:通过抓取大量社交媒体内容,监测公众对热点事件的反应,发现潜在的社会问题。用户行为分析社交媒体的数据类型:帖子和内容:包括用户发布的文本、图片、视频等。用户互动用户信息:包括用户名、粉丝数、关注数等社交信息。社交媒体的反爬虫机制:API限制。

2201_76125261的博客 1337

php的延迟静态绑定static

在公司学习laravel框架过程中,慢慢也在学习php这门后端语言,经常会遇到一些新的知识点,做下记录,加深印象。 首先,延迟静态绑定,适用的对象是类中的静态属性或者静态方法。 class A{ static $name = "Tom"; public function printName() { echo self::$name.'\n'; ...

Liu_Jun_Tao的博客 562

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

php的延迟静态绑定

php的继承模型中有一个存在已久的问题,那就是在父类中引用扩展类的最终状态比较困难 如下例 class A { public static function echoClass() { echo __CLASS__; } public static function test() { self::echoClass();

fisher的博客 3187

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

php 延迟静态绑定

php 延迟静态绑定

Lai助网络科技的博客 483

java接口延迟绑定_PHP延迟静态绑定的深入讲解

前言所谓延迟静态绑定,顾名思义,静态调用时::符号左侧的部分的的绑定是延迟,也就是说不再被解析为定义当前方法所在的类,而是在实际运行时计算的。本文主要介绍了关于PHP延迟静态绑定的相关内容,下面话不多说了,来一起看看详细的介绍吧。嗅到了坏的味道这段时间看项目后台的PHP代码,看到了类似于以下的一段代码,我把它抽出来:class DBHandler {function get() {}}class ...

weixin_33120053的博客 183

PHP面向对象之延迟静态绑定

php5.3已经开始支持延迟静态绑定。 延迟静态绑定指的是在父类中获取子类的最终状态。在父类中,如果出现self关键字,被子类继承后,这个self值的还是父类而不是子类。 如果在父类中出现了self关键字,并且子类继承了含有self的这段代码,那么需要考虑静态延迟绑定。在父类中使用static代替self. 说到底,self到底表示什么?self用在类中,引用自身的静态成员变量,表示的就是类名,完全可以被类名替换掉。被子类继承之后,self还是表示的父类名,而不是子类self了 Demo 未使用延迟静态绑定

Icebreaker 366

PHP 延迟静态绑定 static

首先我们定义一个DomainObject 父类 abstract class DomainObject { public static function create() : DomainObject { return new self(); } } 在编写两个子类 class Shop extends DomainObject { } class User extends DomainObject { } 调用: User::create

sunjindeng123的博客 406

php中延迟绑定,PHP延迟静态绑定实现教程

这段时间看项目后台的PHP代码,看到了类似于以下的一段代码,我把它抽出来:

weixin_34917038的博客 135

php 延迟静态绑定,php中“延迟静态绑定”的使用,php静态

php中“延迟静态绑定”的使用,php静态1

weixin_42525264的博客 110

PHP 延迟静态绑定 功能

从这个名字的定义提取出两个关键点,第一点静态,也就是说这个功能只适用于静态属性或静态方法。 第二点延迟绑定,这个根据下面代码就可以很好的理解 看一下这个例子: class A{ static $name = "Tom"; public function printName(){ echo self::$name."\n"; self::fun(); } static function fun(){ echo "A Class

ding_117的博客 316

php static延迟静态绑定

实际上,self对该类所起的作用与$this对对象所起的作用并不完全相同。self指的不是调用上下文,他指的是解析上下文,因此如果运行上面的列子,将会得到。php5.3之前,在这方面都有严格的限制,产生过很多笨拙的解决方案,php5.3引入了延迟静态绑定 及使用 关键字 static。看起来很优雅整洁,现在我们把常见代码放在一个位置,并用self作为对该类的引用。因此self被解析为定义create的U,而不是解析为调用self的u1类。static类似self,但它指的是被调用的类而不是包含类。

m0_62089210的博客 290

php延迟静态绑定,php延迟静态绑定实例分析

本文实例讲述了php延迟静态绑定的方法。分享给大家供大家参考。具体分析如下:php延迟静态绑定:指类的self,不是以定义时为准,而是以计算时的运行结果为准。先看一个实例header("content-type:text/html;charset=utf-8");class Human{public static function hei(){echo "我是父类的hei()方法";}public...

weixin_32146783的博客 149
上一篇: php错误与异常
下一篇: 客户端服务端消息推送模块设计
码哥说
博客等级 码龄8年 5645粉丝 172原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

码哥说

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

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

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

打赏作者

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

抵扣说明:

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

余额充值