1

Using class constants in PHP, is it possible to enforce that an argument must be one of the constants (like an 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

The case of new Server("foobar") should fail, but because the constructor does not validate $size this works. For brevity I only listed three constant sizes, but assume there are N number of sizes so don't want to do a big block of if checks.

yivi
  • 42,438
  • 18
  • 116
  • 138
Justin
  • 42,716
  • 77
  • 201
  • 296
  • You can force the parameter to be an int instead. This `__construct(int $size)` this way passing the string directly will fail. You get a type error: `Uncaught TypeError: Argument 1 passed to Server::__construct() must be of the type int, string given, ` – Ibu Jul 24 '19 at 00:50
  • 1
    Possible duplicate of [PHP and Enumerations](https://stackoverflow.com/questions/254514/php-and-enumerations) and PHP also has [splenum](https://www.php.net/manual/en/class.splenum.php) which might suit you. – Tigger Jul 24 '19 at 00:51

2 Answers2

2

If your code is as simple as the sample, then it is very easy to implement a check that will do what you want. For example:

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

And the output from above would be:

Fatal error: Uncaught Exception: Invalid size passed. in /devsites/tigger/t.php:18 Stack trace: #0 /devsites/tigger/t.php(24): Server->__construct('foo') #1 {main} thrown in /devsites/tigger/t.php on line 18

Tigger
  • 8,980
  • 5
  • 36
  • 40
0

Consider using the myclabs/php-enum package, which provides the functionality you are looking for.

If you try to pass an invalid enum value, an exception will be thrown.

Package docs: https://github.com/myclabs/php-enum#documentation

atymic
  • 3,093
  • 1
  • 13
  • 26