2012-01-29 62 views
0

確定方法調用的來源,我不知道是否有一個「更好」的方式來做到這一點:在運行時

class Foo { 
    final public function bar() { 
     if (is_subclass_of(get_called_class(), __CLASS__)) { 
      throw new Exception(); 
     } 
    } 
} 

class Bar extends Foo { 
    public function baz() { 
     parent::bar(); // shouldn't be allowed 
    } 
} 

從本質上講,我想在我的父類中的某些方法從美其名曰禁止子類。這需要防彈,我懷疑這是否是,所以如果你知道這可以被規避,那麼我有興趣知道(如果可能的話,以及如何防止它)。

編輯︰對於每個人建議私人方法,這是不是一種選擇,因爲我需要接口保持公開外部訪問。對不起,我猜我認爲這很明顯。

+3

呃,使它'私人'這是否? – Wrikken 2012-01-29 00:17:34

+0

@Wrikken,哈哈..我編輯了我的問題。 – FtDRbwLXw6 2012-01-29 00:32:11

+2

一個函數可以被任何人公開調用,但不能被對象本身調用?這很奇怪。也許你試圖對自己的程序員/子程序員過於強烈地辯護? :) – deceze 2012-01-29 00:37:06

回答

1
class Foo { 
    final public function bar() { 
     if (is_subclass_of(get_called_class(), __CLASS__)) { 
      throw new Exception('No cookies for you!'); 
     } 
     echo 'Failure!'; 
    } 
} 

class Bar extends Foo { 
    public function baz() { 
     try{ 
       Foo::bar(); // shouldn't be allowed 
     } catch (Exception $e){ 
       echo $e->getMessage(); 
     } 
     try{ 
       $func = function() {Foo::bar();}; // is allowed, nags somewhat about it should't be called statically.. 
       $func(); 
     } catch (Exception $e){ 
       echo $e->getMessage(); 
     } 
    } 
} 
$b = new Bar(); 
$b->baz(); 
+0

啊..封閉從來沒有跨過我的腦海。有沒有辦法來防止這種情況,或者改變我的設計來禁止它? +1 – FtDRbwLXw6 2012-01-29 01:43:26

+0

這個特別的調用'debug_backtrace()'並逐步完成它。我會通過調用'register_shutdown_function($ func);'...... – Wrikken 2012-01-29 01:52:56

+0

Touche來對付你。我想我將不得不對沙箱做更多的研究,不允許某些功能等。感謝您的幫助。 – FtDRbwLXw6 2012-01-29 02:14:55

0

我不知道這是否有幫助,但父類中的私有函數不能被子類調用。但如果你需要它公開,我認爲你將不得不在每個孩子中宣佈baz()並拋出異常...

+0

我編輯了我的問題..私人不是一種選擇。而且,既不修改子類,也不修改我的子類。 – FtDRbwLXw6 2012-01-29 00:33:36

3

這不會是「防彈」的。我認爲你沒有辦法做到這一點。

問題的實質是,PHP進程通常在解釋器中運行,並且具有對本地服務器的文件系統訪問權限 - 作爲相對不特權的用戶。但是這仍然足以打開/proc/self/mem,它提供對當前進程的內存空間的讀寫訪問權限。使用它,你可以進入PHP解釋器正在使用的內存和NOP以上你認爲可以提供防彈安全性的代碼。