简体   繁体   中英

PHP - Argument with static variable in called function

I got a doubt while doing this:

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');
       }
}

Now my question is: Is there any way to make the log function in Logger class to accept only the static variables (any static variable) of Logger class? It should not accept any other string or integers as arguments.

My answer was based on the fact that $logLevel contains the name of a static class property.

If you use it as the updated example Logger::$INFO, that will pass the value string(4) "INFO" and this will not work. it needs to pass the value string(8) "log_INFO"

Yes, by using reflection:

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

IMO this kind of enforcement is unnecessary, it adds both complexity and overhead to the code. And the benefits are small.

Coding your necessity like this seams more appropriate to me:

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

The structure above opens up a neat opportunity:

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));
    }
}

What you are asking for is akin to enums in the Java world. Check this question on SO, which has some information on how you can implement similar concepts in PHP.

More specifically, you could implement what you are asking for like this:

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

You could then use it in code like:

Logger::INFO

It isn't perfect, but I believe it is as close as it gets in PHP. To make it bullet-proof, you would have to employ some reflection to check the arguments passed in. This answer on SO has more information on how you can go about implementing it.

It's quite cumbersome but you could do this:

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
    }
}

I've never attempted this myself but I don't see any reason it wouldn't work. Personally, I'd go for something simpler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM