2010-06-03 2 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을 사용할 수 있으며, 원하지 않는 경우 예외를 throw 할 수 있습니다.

+0

C++ 개발자가 아니지만 친구 클래스를 읽은 후 (간략하게), 필자가 찾고있는 것과 똑같은 소리를 들려줍니다. PHP에 상응하는 것이 없다는 것을 압도합니다. – Tim

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에 접두사가 필요하기 때문에 힌트를 얻지 못할 것입니다. 그렇지 않으면 마법 메서드가 무시됩니다.

관련 문제