热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP的CallingScope

作者:Laruence()本文地址:www.laruence.com201206142628.html转载请注明出处昨天在Yaf交流群,大草原同学批评我变懒了,Blog很久没更新了,今天刚好有人在Segmentfalut上问了我一个问题,?我在微博上也做了简单的解答,不过感觉一句话说不

作者: Laruence( ) 本文地址: http://www.laruence.com/2012/06/14/2628.html 转载请注明出处 昨天在Yaf交流群, 大草原同学批评我变懒了, Blog很久没更新了, 今天刚好有人在Segmentfalut上问了我一个问题, ?我在微博上也做了简单的解答, 不过感觉一句话说不

  • 作者: Laruence( )
  • 本文地址: http://www.laruence.com/2012/06/14/2628.html
  • 转载请注明出处

昨天在Yaf交流群, 大草原同学批评我变懒了, Blog很久没更新了, 今天刚好有人在Segmentfalut上问了我一个问题, ?我在微博上也做了简单的解答, 不过感觉一句话说不清楚, 就写篇blog凑个数吧. ;)

问题在这里, ?因为太长, 我就不copy过来了: 这是php中__call和__callStatic在被继承后会产生的bug?

这个问题乍看, 确实很容易让人迷惑, 但实际上, 造成这样的误解的根本原因在于: 在PHP中, 判断静态与否不是靠”::”(PAAMAYIM_NEKUDOTAYIM)符号, 而是靠calling scope.

那么, 什么是calling scope?

在PHP中, 调用一个方法的时候, $this指针指向的对象就是这个方法被调用时刻的calling scope. 对于下面的例子:


在调用bar方法的时候, 处于一个没有calling scope域的上下文中, 所以这个是静态调用.

而对于如下的例子:

test();

在调用bar方法的时候, 处于一个$a对象的上下文中, 也就是说, 此时的calling scope是$a对象, 所以这个其实不是静态调用.

为了验证这一个结论, 请看下面的一个实际例子:

test();
?>

输出什么呢?

object(A)#1 (0) {
}

在调用bar的时候, 这个看似”静态”调用的调用, $this指针却是被赋值的, 指向的是$a对象, 那么这个还算静态调用么?

我举这个例子是为了说明这个问题, 但大家在实际的应用中, 大家尽量要避免使用”::”来调用一个非静态的方法, PHP也会对于这种调用给出一个Strict 警告:

Strict Standards: Non-static method Foo::bar() should not be called statically, assuming $this from incompatible context

也许有人会说这个应该算bug吧? 其实不然, 更多的应该是错误使用造成的, 因为你在一个有calling scope的上下文中采用”静态的形式”调用了一个类的非静态方法所致.

那么PHP为什么要这么设计呢? 考虑下面的例子:


当我们调用父类的构造函数的时候, 我们是有意的要把当前的scope传递给父类的构造函数作为calling scope的.

现在大家对静态调用, 是不是稍微能有更进一步的理解呢? 下午公司马上就要开全体大会, 匆忙而就, 写的可能有点乱, 请大家海涵, 呵呵, thanks


Comments

  • 2012/06/14, 张洋 writes: 鸟哥V5,顶了再看...... :-P
  • 2012/06/14, 张洋 writes: Demon: 13:33:28 更新blog的举动让一群活不下去的人重新站起来了! ......
  • 2012/06/14, ujnjing writes: 鸟哥V5~
  • 2012/06/14, 陆离 writes: 今天看到鸟哥的微博也觉得挺困惑的,正在纠结呢就有了这么一篇博文。学习了。
  • 2012/06/14, jarfield writes: 个人觉得最后一个parent的例子说明PHP此特性的缘由,不是很有说服力。 Java/C++中,均有“子类构造函数调用父类构造函数”的需求。Java对super 关键字做了特殊处理。PHP也完全可以对parent::做特殊处理。类似于Foo::bar的误用,可以直接报错。 这样是否更加安全一些?毕竟很多PHP程序员均有Java/C++的背景,某些概念深入人心。
  • 2012/06/14, xinqiyang writes: 鸟哥的yaf群号是啥? 主要是parent::__construct(); 和普通的 class::staticfunction 记住的了。。。。。
  • 2012/06/14, 子痕 writes: Yaf 群号: 5134185,多谢鸟哥授业解惑,哈哈。
  • 2012/06/14, shirne writes: 似乎明白了。 呵呵
  • 2012/06/15, wizardmin writes: 哈哈,之前也认为是个BUG ”::”来调用一个非静态的方法还是应该给个warning错误
  • 2012/06/15, bill writes: 现丑了。 最后一个例子个人觉得不能很好的说明calling scope。 class B 的实例化对像在调用构造函数的时候,同时也会调用父类(class B)的构造函数,parent::__construct(), 这里的parent不是当前B类的实例化对像,而是Class A本身。所以这里不会是把当前的calling scope传给父类。当前的calling scope是class B的实例化对像。如果传递给父类(class A),那不就是在class A里面用class B的实例化对像(calling scope)? 对于作用域,官方文档的OOP第章好像就有例子说明。 轻拍
  • 2012/06/19, 陈辉云 writes: 报不报strict,看error_reporting的设置。
  • 2012/06/19, huming17 writes: test(); ?> 静态调用函数 public function bar() 定义成 public static function bar() 再静态调用,$this指针不会被赋值。
  • 2012/06/20, wclssdn writes: 给力~~~ 不过. 看到那个$this竟然有值.. 还是A 我就诧异了.... 如果$this->bar2(); 那岂不是报bar2不存在A中? 看来写法的规范性是必须的啊~~ 我就一直没碰到过这问题.. 哈哈哈~~~
  • 2012/06/25, PHP爱好者 writes: 表示我是个规范的写代码的人,不过看了laruence的这篇文章,还是很有收获!
  • 2012/06/25, funlake writes: 给力,又学到东西了,感谢。
  • 2012/07/12, eason writes: 说实话,这种作用域的东西,在任何语言里都有。 一般对Javascript 运行机制,作用域,作用域链有深刻理解的人,再来看php的作用域那就更容易了。
  • 2012/08/09, 奇言妙事-文学奇谈小小说阅读xlinblog.sinaapp.com » Blog Archive » PHP的Calling Scope writes: [...] 本文地址: http://www.laruence.com/2012/06/14/2628.html [...]
  • 2012/08/12, PHP的Calling Scope树林/咖啡 成都专业php网站制作 | 树林/咖啡 成都专业php网站制作 writes: [...] 风雪之隅 ? PHP应用 Posted in: php / Tagged: PHP的Calling, Scope [...]
  • 2012/08/30, 疯狂的火星人 writes: 再看一遍!
  • 2012/09/13, PHP静态调用非静态方法 | 编程·早晨 writes: [...] 好了,对于为什么会出现这个情况的实现原因, 鸟哥的这篇文章有说明 http://www.laruence.com/2012/06/14/2628.html [...]
  • 2012/09/21, x6y6 writes: 用静态方法去调用一个非静态函数,这个为什么不干脆不报错呢,因为按照其他语言,比如Java、C++是直接报错的。
  • 2012/09/21, x6y6 writes: 我有点奇怪,用调用静态方法的方法去调用一个非静态方法,为什么不干脆直接报错呢,因为按照其他语言,比如Java、C++这种情况是直接报错的。
  • 2012/11/19, PHP静态调用非静态方法 « 成人免费资源三级分享网站 writes: [...] 好了,对于为什么会出现这个情况的实现原因, 鸟哥的这篇文章有说明 http://www.laruence.com/2012/06/14/2628.html [...]
  • 2012/11/28, Jason writes: 学习了!!!
  • 2013/03/15, FxYCarl writes: 怪不得我之前在用call_user_function调用对象的方法的时候会出现没在对象上下文的提示...
  • 2013/05/03, noName writes: 我觉得这是在PHP语言设计上有问题。

Related posts:

  • 如何获取一个变量的名字
  • Javascript作用域原理
  • 深入理解PHP原理之函数(Introspecting PHP Function)
  • 深入理解PHP原理之变量分离/引用(Variables Separation)
  • 深入浅出PHP(Exploring PHP)

Copyright © 2010 风雪之隅 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)
推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了一些Java开发项目管理工具及其配置教程,包括团队协同工具worktil,版本管理工具GitLab,自动化构建工具Jenkins,项目管理工具Maven和Maven私服Nexus,以及Mybatis的安装和代码自动生成工具。提供了相关链接供读者参考。 ... [详细]
  • IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,以前是论坛哪里人多 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 本文介绍了在Ubuntu下制作deb安装包及离线安装包的方法,通过备份/var/cache/apt/archives文件夹中的安装包,并建立包列表及依赖信息文件,添加本地源,更新源列表,可以在没有网络的情况下更新系统。同时提供了命令示例和资源下载链接。 ... [详细]
author-avatar
henrysong
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有