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

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

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

那么, 什么是calling scope?

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

  1. <?php
  2. Foo::bar();
  3. ?>

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

而对于如下的例子:

  1. <?php
  2. class A {
  3. public function test() {
  4. Foo::bar();
  5. }
  6. }
  7. $a = new A();
  8. $a->test();

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

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

  1. <?php
  2. class Foo {
  3. public function bar() {
  4. var_dump($this);
  5. }
  6. }
  7. class A {
  8. public function test() {
  9. Foo::bar();
  10. }
  11. }
  12. $a = new A();
  13. $a->test();
  14. ?>

输出什么呢?

  1. object(A)#1 (0) {
  2. }

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

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

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

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

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

  1. <?php
  2. class A {
  3. public function __construct() {
  4. }
  5. }
  6. class B extends A {
  7. public function __construct() {
  8. parent::__construct();
  9. }
  10. }

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

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

转:http://www.laruence.com/2012/06/14/2628.html

更深:

最新文章

  1. Git 命令清单
  2. KlayGE 4.4中渲染的改进(一):只需要SM3的TBDR
  3. mysql 错误 1221 Incorrect usage of union and order by
  4. background-position控制背景位置
  5. CodeForces 492B
  6. (转)AspNetPager查询分页问题(点击页码,不再是查询后的数据集)viewstate解决
  7. 『openframeworks』shader制作三角形马赛克效果
  8. Android引入高速缓存的异步加载全分辨率
  9. C语言 &#183; FJ的字符串
  10. 第2章KNN算法笔记_函数classify0
  11. es6-promise源代码重点难点分析
  12. Mlecms 反射型xss &amp;&amp; 后台任意文件下载
  13. Tomcat的管道
  14. haproxy4-acl配置
  15. 拷贝文件到服务器 提示FTP文件夹错误
  16. web架构延变
  17. 关于解决logging模块写出的日志信息重复的问题
  18. 4N - 素数回文
  19. AAAI 2018 论文 | 蚂蚁金服公开最新基于笔画的中文词向量算法
  20. 去掉input获取focus时的边框

热门文章

  1. Delphi 常用属性说明(超长)
  2. 开源项目live555学习心得
  3. POJ 2762 Going from u to v or from v to u? (Tarjan) - from lanshui_Yang
  4. Intersecting Lines(数学)
  5. uestc 250 数位dp(水)
  6. 与一线Linux嵌入式开发project师的对话
  7. Null指针
  8. unix IO笔记
  9. (IOS)N duplicate symbols for architecture i386
  10. 函数重载不仅仅是看其参数,还要看是否有const修饰