【问题标题】:Using class constants as Enumerations使用类常量作为枚举
【发布时间】:2019-12-02 01:36:03
【问题描述】:

在 PHP 中使用类常量,是否可以强制参数必须是常量之一(如 Enum)?

Class Server {
    const SMALL = "s";
    const MEDIUM = "m";
    const LARGE = "l";

    private $size;

    public function __construct($size) {
        $this->size = $size
    }
}

$small = new Server(Server::SMALL); // valid
$foobar = new Server("foobar");      // also valid. This should fail instead

new Server("foobar") 的情况应该会失败,但是因为构造函数没有验证 $size 这有效。为简洁起见,我只列出了三个常量大小,但假设有 N 个大小,所以不想做大量的 if 检查。

【问题讨论】:

  • 您可以强制参数为 int。这个__construct(int $size) 这种方式直接传递字符串会失败。你得到一个类型错误:Uncaught TypeError: Argument 1 passed to Server::__construct() must be of the type int, string given,
  • PHP and Enumerations 的可能副本,PHP 也有可能适合您的 splenum

标签: php class enums constants


【解决方案1】:

8.1 发布后,您将可以to use actual enumerations

那么你就可以做到:

enum ServerType {
    case SMALL  = "s";
    case MEDIUM = "m";
    case LARGE  = "l";
}

class Server {
    private ServerType $type;

    public function __construct(ServerType $type) {
        $this->type = $type;
    }
}

你可以这样做:

$server = new Server(ServerType::SMALL);

// the following works, gets ServerType::MEDIUM
$server = new Server(ServerType::from('m'));

// but this fails and throws a ValueError exception
// since the `xl` case is not defined for the enumeration
$server = new Server(ServerType::from('xl')); 

【讨论】:

    【解决方案2】:

    如果您的代码与示例一样简单,那么很容易实现一个检查来满足您的需求。例如:

    class Server {
        const SMALL = "s";
        const MEDIUM = "m";
        const LARGE = "l";
    
        private $size;
    
        public function __construct($size) {
            switch($size) {
                case self::SMALL:
                case self::MEDIUM:
                case self::LARGE:
                    $this->size = $size;
                    break;
                default:
                    throw new Exception('Invalid size passed.');
            }
        }
    }
    
    $S = new Server("s");
    $Fail = new Server("foo");
    

    上面的输出是:

    致命错误:未捕获的异常:传递的大小无效。在 /devsites/tigger/t.php:18 堆栈跟踪:#0 /devsites/tigger/t.php(24): Server->__construct('foo') #1 {main} throw in /devsites/tigger/t .php 在第 18 行

    【讨论】:

      【解决方案3】:

      考虑使用myclabs/php-enum 包,它提供了您正在寻找的功能。

      如果你试图传递一个无效的枚举值,将会抛出一个异常。

      包文档:https://github.com/myclabs/php-enum#documentation

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-21
        • 1970-01-01
        • 2011-01-21
        • 2018-05-25
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多