PHP - 在被调用的函数中使用静态变量进行参数传递
PHP - 在被调用的函数中使用静态变量进行参数传递
在进行这个操作时,我有一个疑问:
class Logger { public static $log_INFO = 'INFO'; public static $log_ERROR = 'ERROR'; public function log($logLevel, $param2, $param3) { // 将日志写入某个文件 } } class Midea { public function fn1 { $logger = new Logger(); $logger->log(Logger::$log_INFO, 'some', 'some2'); } }
现在我的问题是:有没有办法让Logger类中的log函数只接受Logger类的静态变量(任何静态变量)作为参数?它不应该接受任何其他字符串或整数。
在上述代码中,出现了一个问题,即在调用函数中使用静态变量参数。这是因为在log函数中,参数$logLevel的类型被定义为LoggerStatus,而LoggerStatus是一个抽象类,不能直接实例化。因此,无法将静态变量$log_INFO或$log_ERROR作为参数传递给log函数。
要解决这个问题,我们可以将LoggerStatus类定义为抽象类,以便只能在被继承后使用。这样一来,我们可以将$log_INFO和$log_ERROR定义为其子类实例,并将它们作为参数传递给log函数。
下面是修改后的代码:
abstract class LoggerStatus { protected $status; 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 } }
通过将LoggerStatus定义为抽象类,我们确保只能通过继承来使用它。然后,我们将LoggerStatusInfo和LoggerStatusError定义为其子类,并将它们的实例分别赋值给$log_INFO和$log_ERROR静态变量。最后,我们可以将这些静态变量作为参数传递给log函数,而不会出现类型错误。
这样,我们就解决了在调用函数中使用静态变量参数的问题。
PHP中的问题 - 调用函数中的静态变量参数
问题原因:问题出现是因为$logLevel包含了一个静态类属性的名称。如果将其作为更新示例Logger::$INFO使用,那么将传递值string(4) "INFO",这将不起作用,它需要传递值string(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 } }
个人认为,这种强制性的实现是不必要的,它增加了代码的复杂性和开销,而收益却很小。更合适的方式是根据需求编写代码,如下所示:
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)); } }
最后一个案例(包含处理每个级别的函数的级别数组)不需要前缀。添加前缀的需求出现在创建ReflectionProperty对象时,构造函数接受$class_name和$property_name作为参数。因此,我们需要Logger::$SomeLoggingLevel的值包含其准确的名称“SomeLoggingLevel”,如果它们都使用相同的前缀,比如“log_”,我们可以调用new ReflectionProperty($class_name, "log_".$property_name),因此Logger::$log_INFO的值必须确切为“INFO”(因为在创建ReflectionProperty时我们将添加前缀)。
在PHP中,如果想要实现类似于Java中的枚举的功能,可以使用常量来实现。这样可以定义一些固定的值,然后在代码中使用。但是这种方式并不完美,因为常量的值可以被滥用。为了使其更加健壮,可以使用反射来检查传入的参数是否有效。
具体实现方法如下:
class Logger { const INFO = 1; const ERROR = 2; };
然后可以在代码中使用,例如:
Logger::INFO
如果希望更加严格,可以结合反射来验证传入的参数是否有效。下面这段代码可以提供更多关于如何实现的信息:
// 这段代码可以提供更多关于如何实现的信息
通过这种方式,可以在PHP中实现类似于枚举的功能。但是需要注意的是,这种方式仍然有一些弱点,因为常量的值可以被滥用。为了解决这个问题,可以使用反射来验证传入的参数是否有效。通过结合常量和反射,可以在PHP中实现类似于枚举的功能。