zoukankan      html  css  js  c++  java
  • php calling scope

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

    更深:

  • 相关阅读:
    django缓存机制
    RBAC基于角色访问控制
    Book系列十大接口
    xadmin的使用
    JWT认证
    自动生成接口文档
    drf的过滤排序分页异常处理
    认证权限解析频率
    python学习之内置模块补充
    python学习之内置模块补充作业
  • 原文地址:https://www.cnblogs.com/youxin/p/3256048.html
Copyright © 2011-2022 走看看