2012-05-21 4 views
1

호출 된 함수에서 정적 변수와 인수이하는 동안 :PHP - 나는 의심을 가지고

class Logger { 
     public static $log_INFO = 'INFO'; 
     public static $log_ERROR = 'ERROR'; 
     public function log($logLevel, $param2, $param3) { 
       // Write log to some file 
     } 
} 

class Midea { 
     public function fn1 { 
      $logger = new Logger(); 
      $logger->log(Logger::$log_INFO, 'some', 'some2'); 
     } 
} 

이제 내 질문은 : 만 정적을 받아 Logger 클래스의 로그 기능을 어떤 방법이 있나요 Logger 클래스의 변수 (정적 변수)? 다른 문자열이나 정수를 인수로 받아 들여서는 안됩니다.

+0

여기에 대한 답변보기 : http://stackoverflow.com/questions/6568857/possible-to-test-if-a-variable-is-static-in-php – Julien

+0

내 코드는 다음과 같은 결정 : a) 모든 로그 수준 속성에는 "log_"접두어가 붙습니다. 또는 b) 모든 로그 수준 속성은 자체 속성 이름을 값으로 갖습니다. a) 올바른 ReflectionProperty를 얻기 위해 코드를 변경할 수 있습니다. b) 코드가 이미 올바른 경우입니다. –

답변

3

내 대답은 $ logLevel에 정적 클래스 속성의 이름이 들어 있다는 사실을 기반으로했습니다.

업데이트 된 Logger :: $ INFO로 사용하면 문자열 (4) "INFO" 값이 전달되고 작동하지 않습니다. 이는 리플렉션을 이용하여, 값 스트링 (8) "LOG_INFO"

예를 전달해야 : 시행

public function log($logLevel, $param2, $param3) { 
    $reflection_property = new ReflectionProperty(get_called_class(), $logLevel); 
    if($reflection_property->isStatic()) { 
     // rest of the code 
    } 
} 

IMO 이런이 불필요, 상기 코드에 복잡성 및 오버 헤드 모두를 추가한다. 그리고 혜택은 적습니다. 이 나에게 더 적절한 솔기처럼

당신의 필요성을 코딩 :

public static function $log_levels = array('INFO', 'ERROR'); 
public function log($log_level, $param2, $param3) { 
    if(in_array($log_level, static::$log_levels)) { 
     // code 
    } 
} 

구조는 위의 깔끔한 기회를 열어 :

public static function $log_levels = array(
    'INFO' => array('Logger', 'handleInfoLogs'), 
    'ERROR' => array('Logger', 'handleErrorLogs') 
); 
public function log($log_level, $param2, $param3) { 
    if(array_key_exists($log_level, static::$log_levels)) { 
     return(static::$log_levels[$log_level]($param2, $param3)); 
    } 
} 
+0

설명해 주셔서 감사합니다. 나는 당신의 대답에 동의합니다. 이 경우에 접두사로 "log_"을 ​​추가해야하는 이유를 설명해 주시겠습니까? 마지막 케이스 (각 레벨을 처리하는 함수가있는 레벨 배열)의 경우 – Jebin

+0

은 접두어가 필요하지 않습니다. –

+0

새로운 ReflectionProperty 객체를 만들 때 접두어가 필요하며 생성자는 $ class_name 및 $ property_name을 인수로 사용합니다. Logger :: $ SomeLoggingLevel의 값은 "SomeLoggingLevel"이라는 정확한 이름을 포함해야합니다. 모두 "log_"와 같은 접두사를 사용하면 new ReflectionProperty ($ class_name, "log _". $ property_name)를 호출 할 수 있습니다. Logger :: $ log_INFO의 값은 정확히 "INFO"여야합니다 (ReflectionProperty를 만들 때 접두어를 추가하기 때문에) –

1

Java 세계에서 열거 형과 비슷합니다. PHP에서 비슷한 개념을 구현하는 방법에 대한 정보가있는 this 질문을 확인하십시오.

class Logger { 
    const INFO = 1; 
    const ERROR = 2; 
}; 

당신은 다음과 같은 코드를 사용할 수 있습니다 :

구체적

, 당신은 이런 식으로 당신이 요구하는 것을 구현할 수

Logger::INFO 

그것은 완벽하지 않습니다,하지만 난 믿는다 PHP에서와 거의 비슷합니다. 그것을 방탄으로 만들려면 전달 된 인수를 확인하기 위해 약간의 리플렉션을 사용해야합니다. This SO에 대한 답은 구현 방법에 대한 자세한 정보가 있습니다.

+0

사실, 열거 형이 여기에서 더 효율적일 것입니다. –

+1

여기에 단점은 남용 될 수있는 Logger :: INFO (** int (1) **) 약점의 값을 전달한다는 것입니다. –

+0

올바른 것이므로 구현하는 클래스는 전달 된 인수가 유효한지 확인하기 위해 이것을 반사 위도와 결합해야합니다. [이] (http : // stackoverflow.com/questions/1528280/how-to-implement-enum-like-functionality-in-php)에 관한 질문이 관련되어 있습니다. – Jeshurun

1

을 그것은 아주 성가신하지만 당신이 할 수 있습니다 :

abstract class LoggerStatus 
{ 
    public function __toString() 
    { 
     return $this->status; 
    } 
} 

class LoggerStatusInfo extends LoggerStatus 
{ 
    protected $status = 'INFO'; 
} 

class LoggerStatusError extends LoggerStatus 
{ 
    protected $status = 'ERROR'; 
} 

class Logger { 
    public static $log_INFO; 
    public static $log_ERROR; 

    public function __construct() 
    { 
     self::$log_INFO = new LoggerStatusInfo(); 
     self::$log_ERROR = new LoggerStatusError(); 
    } 

    public function log(LoggerStatus $logLevel, $param2, $param3) { 
      // Write log to some file 
    } 
} 

본인은 본 적이 없지만 작동하지 않을 이유는 없습니다. 개인적으로, 나는 더 간단한 것을 갈 것입니다.

+0

LoggerStatus ** abstract **를 확장 후에 만 ​​사용할 수있게하십시오. –

+0

좋은 생각. 내가 제안한대로 수정했습니다. – Okonomiyaki3000

관련 문제