6

I've read here about enumarations and their "implementation"

PHP and Enumerations

point is, why use enums, when not for type hinting?

but this implementation does not allow use for type hinting. Because the enum entries are all strings.

is there a way I can say

function($a) {

}

$a must be 'foo', 'bar' or 'baz'

in PHP?

I use phpstorm/intellij so if there is another way to do that, that would be fine too. E.g. say in the doc but with autocompletion magic from phpstorm, or maybe compile errors.

yivi
  • 42,438
  • 18
  • 116
  • 138
Toskan
  • 13,911
  • 14
  • 95
  • 185

2 Answers2

11

Starting in PHP 8.1, you'll be able to use actual enumerations.

enum A {
    case FOO = 'foo';
    case BAR = 'bar';
    case BAZ = 'baz';
}

Then in your function a(), you'd type-hint for the enumeration A.

function a(A $a) {
    echo $a->value;
}

Now a($a) would only accept:

a(A::FOO);
a(A::BAR);
a(A::BAZ);

or even:

a(A::from('bar'));

but any input that's not a valid case would fail with a ValueError exception.

yivi
  • 42,438
  • 18
  • 116
  • 138
4

There is no built-in way in PHP to require that a passed string has a certain value; not even in PHP7. You can type-hint objects and arrays that I know of. Enumerations would solve that problem, but PHP doesn't support enumerations.

If you really, really need that, maybe you should consider a strongly-typed programming language.

If you are stuck with PHP

An easy way you can make sure your string follows some rules is to make it a class that blows up if it's not one of those values.

Try this

<?php

class WeekDay {
    private $value;

    public function __construct($value) {
        if (!in_array($value, ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']))
            throw new Exception("Not a week day.");
        else
            $this->value = $value;
    }

    public function __toString() {
        return $this->value;
    }
}

function echoWeekDay(WeekDay $weekDay) {
    echo $weekDay . "\n";
}

echoWeekDay(new WeekDay("Tuesday"));
echoWeekDay(new WeekDay("Saturday"));

Run with

~/Code/stack-overflow $ php enums.php
Tuesday
PHP Fatal error:  Uncaught exception 'Exception' with message 'Not a week day.' in /Users/marianol/Code/stack-overflow/enums.php:8
Stack trace:
#0 /Users/marianol/Code/stack-overflow/enums.php(23): WeekDay->__construct('Saturday')
#1 {main}
  thrown in /Users/marianol/Code/stack-overflow/enums.php on line 8

Fatal error: Uncaught exception 'Exception' with message 'Not a week day.' in /Users/marianol/Code/stack-overflow/enums.php:8
Stack trace:
#0 /Users/marianol/Code/stack-overflow/enums.php(23): WeekDay->__construct('Saturday')
#1 {main}
  thrown in /Users/marianol/Code/stack-overflow/enums.php on line 8

By the way, enumerations are not primarily used for type-hinting on function arguments. For example, databases use enum fields to optimise storage efficiency (since enums need much less storage space than strings), and if your programming language doesn't offer an enum data type, you have to be very careful when you retrieve, modify and persist to an enum data type back to your database.

mlg
  • 1,447
  • 15
  • 19
  • good point about the database column. I still stand my point, how many strings are used as function arguments when working as a software developer? how many?? and that is always a very well defined set of strings, that is not some "well do whatever you want". And there is no way to express that this set of strings is available. It really is a pity having to reach for the docs for each single function. – Toskan May 09 '16 at 18:33
  • @Toskan: And it's a good point. Having the compiler (or the interpreter) help you to find most of the issues is exactly what you get with strongly-typed languages. – mlg May 10 '16 at 05:48
  • well yes true, but statically typed languages have drawbacks too. It would have been good enough if type hinting worked properly in php and there would be enumerations. It sounds like asking a lot but it really isn't. I wonder how python 3.x type hinting works, as it seems to have enums since 3.4. Not having these kind of things is just mickey mouse programming. – Toskan May 10 '16 at 06:05