2010-09-12 53 views
1

我正在研究我的應用程序,發現了靜態調用但未定義爲擴展相同類的靜態方法的奇怪行爲。最終,這個方法可以訪問和修改調用者保護的變量和方法。 這裏是例如我的代碼:靜態方法可以訪問調用者對象,錯誤或功能?

<?php 

class object 
{ 
    private $version; 

    protected $alteredBy = 'nobody'; 

    public function __construct() 
    { 
     $this->version = PHP_VERSION; 

     $this->objectName = get_class($this); 

     echo sprintf("<pre><strong>New %s Created</strong>", $this->objectName); 

    } 

    public function __destruct() 
    { 
     echo sprintf("</pre><strong>Source Code</strong><div>%s</div>", highlight_file(__FILE__, true)); 
    } 
} 

class superApplication extends object 
{ 
    public function __toString() 
    { 
     echo "\nCalling third party object statically like thirdParty::method()\n"; 

     echo thirdParty::method(); 

     echo "\nCalling third party object statically via call_user_func()\n"; 

     echo call_user_func(array('thirdParty','method')); 

     echo sprintf("New Object params\n%s", print_r($this, true)); 

     return sprintf("%s: done\n", $this->objectName); 
    } 
} 

class thirdParty extends object 
{  
    public function method() 
    { 
     if(is_object($this)) 
     { 
      $this->alteredBy = __CLASS__; 

      return sprintf(
       "<span style=\"color:red\">Object '%s' was altered successfully by %s class</span>\n", 
       get_class($this), 
       __CLASS__ 
      ); 
     } 
     else return "Cannot access caller object\n\n";   
    } 
} 

print new superApplication; 
?> 

此行爲沒有記錄,所以我不知道是不是錯誤或功能,並可以將它導致的安全問題?

更新。 我知道,$這是不允許的靜態方法內,這種行爲出現在PHP版本5.2.11

+0

<評論刪除> – 2010-09-12 21:54:16

回答

1

在PHP 5.3考慮這個例子:

<?php 
     error_reporting(E_ALL | E_STRICT); 

     class A 
     { 
       private $a = 'A'; 
       protected $b= 'B'; 
       public $c = 'C'; 
     } 

     class B extends A 
     { 
       public function __construct() 
       { 
         var_dump($this->a, $this->b, $this->c); 
         C::test(); 
         var_dump($this->a, $this->b, $this->c); 
       } 
     } 

     class C extends A 
     { 
       public function test() 
       { 
         $this->a = null; 
         $this->b = null; 
         $this->c = null; 
       } 
     } 

     new B(); 
?> 

輸出是:

PHP Notice: Undefined property: B::$a in ... on line 15 
NULL 
string(1) "B" 
string(1) "C" 
PHP Strict Standards: Non-static method C::test() should not be called statically, assuming $this from incompatible context in ... on line 16 
NULL 
NULL 
NULL 

會發生什麼事是,C::test()$this指針被認爲是從new B()實例$this。所以它的行爲就像B的成員函數,但是有C的訪問權限。

它只能從B訪問從A保護和公共變量和公共變量。

注意,調用C::test()之前,$this->a觸發的通知。呼叫之後,它不再這樣做了,因爲變量是在呼叫中創建的。但是A的私有變量在任何時候都不可訪問。

所以,是的,這是嚴格來說,被認爲是無效的PHP 5.3。即使早期版本可以在沒有警告的情況下執行此操作(我沒有檢查或研究過),但您絕不應該依賴這種行爲,因爲它顯然是OOP的濫用。

相關問題