php calling scope

昨天在Yaf交流羣, 大草原同窗批評我變懶了, Blog好久沒更新了, 今天恰好有人在Segmentfalut上問了我一個問題,  我在微博上也作了簡單的解答, 不過感受一句話說不清楚, 就寫篇blog湊個數吧. ;)php

問題在這裏,  由於太長, 我就不copy過來了: 這是php中__call和__callStatic在被繼承後會產生的bug?html

這個問題乍看, 確實很容易讓人迷惑, 但實際上, 形成這樣的誤解的根本緣由在於: 在PHP中, 判斷靜態與否不是靠」::」(PAAMAYIM_NEKUDOTAYIM)符號, 而是靠calling scope.segmentfault

那麼, 什麼是calling scope?函數

在PHP中, 調用一個方法的時候, $this指針指向的對象就是這個方法被調用時刻的calling scope. 對於下面的例子:this

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

在調用bar方法的時候, 處於一個沒有calling scope域的上下文中, 因此這個是靜態調用.spa

而對於以下的例子:設計

  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對象, 因此這個其實不是靜態調用.指針

爲了驗證這一個結論, 請看下面的一個實際例子:htm

  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

更深:

相關文章
相關標籤/搜索