PHP: Class 输入参数类型声明中的常量

PHP: Class constants in type declarations of input paramaters

对于自定义记录器,我想强制调用者传递在 Psr\Log\LogLevel.

中定义的有效 class 常量

这个 class 定义如下:

namespace Psr\Log;
/**
 * Describes log levels.
 */
class LogLevel
{
    const EMERGENCY = 'emergency';
    const ALERT     = 'alert';
    const CRITICAL  = 'critical';
    const ERROR     = 'error';
    const WARNING   = 'warning';
    const NOTICE    = 'notice';
    const INFO      = 'info';
    const DEBUG     = 'debug';
}

记录器的函数(错误)看起来像:

public static function log($log, LogLevel $logLevel = null): void {
   // .....
}

这不起作用,因为 LogLevel::DEBUG 例如是一个字符串而不是 class 的实例。有没有办法在 PHP 类型声明中强制执行 class 常量?因为如果我定义 string 那么你显然可以传递任何字符串,但我只想允许声明的常量。

如果你有 Phpstorm,你可以使用新的 #[ExpectedValues] 属性功能:https://blog.jetbrains.com/phpstorm/2020/10/phpstorm-2020-3-eap-4/#expectedvalues_examples

没有简单的方法,但您可以检查插入的字符串是否与某些值匹配

function checkLog(string $logLevel){
  $acceptableValues = array("emergency", "error", "debug");
  if(!in_array($logLevel, $acceptableValues) die();
}

用您的 class.

的常量替换数组中的字符串

PHP 没有常量限制,只有类型。

但您可以采用如下解决方法:

class LogLevel
{
    protected string $logName;

    private function __construct(string $logName)
    {
        $this->logName = $logName;
    }
    public function getName(): string
    {
        return $this->logName;
    }

    public static function emergency(): self
    {
        return new self('emergency');
    }

    public static function alert(): self
    {
        return new self('alert');
    }

    public static function critical(): self
    {
        return new self('critical');
    }
    // create the other constants here
}

现在你的静态函数可以工作了

public static function log($log, LogLevel $logLevel = null): void {
   // .....
}

$logLevel会收到LogLevel::emergency()LogLevel::critical()等,调用$logLevel->getName()

即可得到关卡名称