The values could have been 1, 2, and 3 or 'x', 'y', and 'z' and the app would work the same.
Now imagine that the app allows the user to select from a number of duration intervals and one is declared as
const INTERVAL_1_WEEK = '1week';
A coder might by mistake use it, e.g. in DateTime::modify(). It would be a programming error to do that but you can imagine how it might happen. And it could lead to a nasty bug that’s hard to understand. In our team we had the habit of assigning meaningful string values to such constants and we ran into a nasty bug of exactly this kind.
Once we figured it out I saw that the programming error would have been avoided or detected early if we had used something like a Ruby symbol. PHP doesn’t have them so I wondered if we might approximate them with opaque values, e.g.
Debugging such values with XDebug will be hard. You’ll have to look up the meaning.
Likely value objects would do:
private string $format;
private function __construct()
public static function csv(): self
$new = new self();
$new->format = 'csv';
// same for other formats
public function convert(Format $format)
As an alternative, you can leave constructor public and validate value there.
As another alternative, use constants as usual but validate value where it’s used.