2010-06-03 54 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提示这些方法,因为你需要给它们加上前缀或其他东西,否则魔法方法就会被忽略。

相关问题