Sometimes the values of our constants in PHP don’t matter because they are only ever used in comparisons and array keys. For example, the app might have options like these
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:
class Format
{
private string $format;
private function __construct()
{
}
public static function csv(): self
{
$new = new self();
$new->format = 'csv';
return $new;
}
// same for other formats
}
class Converter
{
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.