2010-06-03 51 views
4

PHP5中有一種方法只允許某個類或某組類調用某個特定的函數嗎?例如,假設我有三個類(「Foo」,「Bar」和「Baz」),所有這些類都使用了類似的命名方法,我希望Bar能夠撥打Foo::foo()但拒絕Baz提供該電話的能力:PHP5:限制對某些類的函數訪問

class Foo { 
    static function foo() { print "foo"; } 
} 

class Bar { 
    static function bar() { Foo::foo(); print "bar"; } // Should work 
} 

class Baz { 
    static function baz() { Foo::foo; print "baz"; } // Should fail 
} 

Foo::foo(); // Should also fail

有不一定富,酒吧和巴茲,所以使用protected或類似的修飾不會幫之間的繼承;然而,這些方法不一定是靜態的(爲了簡單起見,我在這裏做了它們)。

回答

7

有沒有語言功能可以給你這種行爲,聽起來像你想模仿類似C++的朋友類?

但是,在foo()方法中,您可以使用debug_backtrace來找出您的調用者是誰,並在不需要時拋出異常!

+0

不是C++開發者,但是在閱讀(簡要地)關於朋友類之後,聽起來像我正在尋找的行爲。令人沮喪的是,沒有PHP的等價物。 – Tim 2010-06-03 14:27:45

3

我已經創建了一個可能有幫助的功能。

class HelperClass 
{ 

    static function callOnlyByClass($class_name, $function_name = NULL) 
    { 
     $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); 
     $caller_class = $backtrace[2]["class"]; 
     if($caller_class !== $class_name) { 
      throw new Exception("Only $class_name is allowed to call this function. Was called by $caller_class."); 
     } 
     if(! is_null($function_name)) { 
      $caller_function = $backtrace[2]["function"]; 
      if($caller_function !== $function_name) { 
       throw new Exception("Only $class_name::$function_name is allowed to call this function. Was called by $caller_class::$caller_function."); 
      } 
     } 
    } 

} 
1

一個忽悠的一點,但如果你想更簡單更少的內存密集型替代使用debug_backtrace()你可以需要額外的參數,將有一些具體祕密值的方法。因此,例如: -

class Foo { 
    static function foo($arg='') { 
     if ($arg != 'act6hd56') { 
      throw new Exception('Cannot call this method from any class except Bar'); 
     } 
     print "foo"; 
    } 
} 

class Bar { 
    static function bar() { Foo::foo('act6hd56'); print "bar"; } // Works 
} 

Foo::foo(); // Throws exception 

這並不能阻止有人找過代碼,並圍繞它的工作,但與異常明智的消息,你應該能夠傳達你打算如何使用的類。

你甚至可以更進一步,實現非常相似的東西C++的friend classes使用PHP的魔術__call()__callStatic()方法,這將意味着你可以做祕密檢查,不污染的實際方法。這樣做的缺點是你不會得到IDE提示這些方法,因爲你需要給它們加上前綴或其他東西,否則魔法方法就會被忽略。

相關問題