昨天在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

更深:

php calling scope的更多相关文章

  1. PHP的Calling Scope(::调用非静态方法)

    今天在群里发现有人说,PHP可以用::调用非静态方法,一致没这么试过,发现了鸟哥的blog写了这个问题的具体解释,就搬过来: 这个问题乍看, 确实很容易让人迷惑, 但实际上, 造成这样的误解的根本原因 ...

  2. Scope Directive

    ---------------------------Scope-------------------------------- https://docs.angularjs.org/guide/sc ...

  3. Angular之 Scope和 Directive

    ---------------------------Scope-------------------------------- https://docs.angularjs.org/guide/sc ...

  4. PHP面试题目搜集

    搜集这些题目是想在学习PHP方面知识有更感性的认识,单纯看书的话会很容易看后就忘记. 曾经看过数据结构.设计模式.HTTP等方面的书籍,但是基本看完后就是看完了,没有然后了,随着时间的推移,也就渐渐忘 ...

  5. Speeding up AngularJS apps with simple optimizations

    AngularJS is a huge framework with that already has many performance enhancements built in, but they ...

  6. Exploring Python Code Objects

    Exploring Python Code Objects https://late.am/post/2012/03/26/exploring-python-code-objects.html Ins ...

  7. Angular源代码学习笔记-原创

    时间:2014年12月15日 14:15:10 /** * @license AngularJS v1.3.0-beta.15 * (c) 2010-2014 Google, Inc. http:// ...

  8. 【转】Build Your own Simplified AngularJS in 200 Lines of JavaScript

    原文:http://blog.mgechev.com/2015/03/09/build-learn-your-own-light-lightweight-angularjs/ Build Your o ...

  9. Sequelize-nodejs-9-Scopes

    Scopes作用域 Scoping allows you to define commonly used queries that you can easily use later. Scopes c ...

随机推荐

  1. 用户管理_组管理_设置主机名_UGO_文件高级权限_ACL权限

    用户管理: 添加用户:useradd tom 设置密码:passwd tom 切换账户: su - tom (不加-也能切换,但是 -会有两点不同 1.有-会切换到该用户的主目录  2.会切换到该用户 ...

  2. VC编程之设置客户区背景图片

    在很多系统中出于美观的需要常常要设置背景图片.下面我介绍一种在客户区设置背景图片的简单方法. 1 .将背景bmp 图片导入到工程,资源ID 这里假设为 IDB_BITMAP1 2 .在视图类添加如下代 ...

  3. Filter 知识总结

    Filter对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压 ...

  4. HDU 4569 Special equations (数学题)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4569 题意:给你一个最高幂为4的一元多项式,让你求出一个x使其结果模p*p为0. 题解:f(x)%(p ...

  5. break 与continue的区别

    //break是结束整个循环体,continue是结束单次循环 比方说: while(x++ < 10){ if(x == 3) { break; } printf("%d\r\n&q ...

  6. C#主键类型选择

    1.SQL Server中两种常用的主键数据类型:int(或者bigint)+标识列(又称自动增长字段) uniqueidentifier(又称Guid.UUID) 2.Guid算法是一种可以产生唯一 ...

  7. 网上的一个helpdesk流程,将来备用

  8. ThinkPHP - 登录模块,核心代码

    /** * 登录成功 * @return [type] [description] */ public function checkLogin($data) { $user = M($this-> ...

  9. dlib库学习之一

    dlib库学习之一 1.介绍 跨平台 C++ 通用库 Dlib 发布 ,带来了一些新特性,包括概率 CKY 解析器,使用批量同步并行计算模型来创建应用的工具,新增两个聚合算法:中国低语 (Chines ...

  10. 64位win8 配置Apache2.4+mod_msgi4.4.21+django1.8.6+python3.4

    学习了很多前人分享的资料,整理如下: 安装步骤: 一.安装python3.4        下载 python-3.4.3.amd64.msi 直接安装         地址:https://www. ...