zoukankan      html  css  js  c++  java
  • 关于PHP中”::”能够调用一个非静态的方法的解释

     什么是calling scope?

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

    <?php
    Foo::bar();
    ?>

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

    而对于如下的例子:

    <?php
    class A {
         public function test() {
             Foo::bar();
         }
     }
    $a = new A();
    $a->test();

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

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

    <?php
     class Foo {
         public function bar() {
             var_dump($this);
         }
     }
     class A {
         public function test() {
             Foo::bar();
         }
     }
     $a = new A();
     $a->test();
    ?>

    输出什么呢?

    object(A)#1 (0) {
    }

    在调用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为什么要这么设计呢? 考虑下面的例子:

    <?php
     class A {
        public function __construct() {
        }
     }
      class B extends A {
        public function __construct() {
            parent::__construct();
       }
       }

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

    对于使用::调用一个类的非静态方法这个操作其实是错误,我们要使用正确的方式来调用一个类中的非静态方法,对于A::get()这个方法,虽然能够调用到A类的非静态方法get(),但是会产生一个错误提示

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

    所以,我们要尽量使用正确的方式来调用非静态方法。

    转自鸟哥博客:

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

  • 相关阅读:
    HTML5 GAME TUTORIAL(三): Draw shapes, paths and text(译)
    HTML5 GAME TUTORIAL(二): Set-up an HTML5 canvas(译)
    HTML5 GAME TUTORIAL(一): Develop an HTML5 game(译)
    实现一个扇形的几种方法
    What Is Webpack and How Does It Work(译)
    What Does Webpack Do, and How Do I Use It for My Website?(译)
    Getting Started with NestJS(译)
    vue 渲染出来的列表点击的时候需要单独给li添加一个class
    移动端使用isscroll.js input无法获取焦点(就是点了没反应啦!)
    移动端适配之rem 笔记
  • 原文地址:https://www.cnblogs.com/leaf-blog/p/11525973.html
Copyright © 2011-2022 走看看