Open dbalabka opened 4 years ago
This is what I use:
<?php
declare(strict_types=1);
namespace App\Doctrine;
use Dbalabka\Enumeration\Enumeration;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\StringType;
abstract class EnumType extends StringType
{
abstract protected function getClass(): string;
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
}
assert($value instanceof Enumeration);
return $value->name();
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
}
$class = $this->getClass();
return $class::valueOf($value);
}
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}
<?php
declare(strict_types=1);
namespace App\Doctrine;
use App\Entity\Questionnaire\Question\ChoiceTemplate;
class ChoiceTemplateType extends EnumType
{
public function getName()
{
return 'choice_template';
}
protected function getClass(): string
{
return ChoiceTemplate::class;
}
}
@Warxcell thanks for your contribution! PHP 8.1 will support Enums out of the box:
https://php.watch/versions/8.1/enums
Probably, the only feature that isn't supported, yet, is Maybe
monad that will be implemented in future scope:
https://wiki.php.net/rfc/adts
PHP 8.1 will be released around November 2021. So I'm going to archive this repository somewhere after 8.1 release.
If you are already using this library let me known then I can think about what I can do for you.
lol... I don't see any benefits from 8.1 enums.... They behave almost like constants. The most important to me using enums is the ability to assign numberable properties to them. :(
enum HTTPStatus: int {
case OK = 200;
case ACCESS_DENIED = 403;
case NOT_FOUND = 404;
public function label(): string {
return static::getLabel($this);
}
public static function getLabel(self $value): string {
return match ($value) {
HTTPStatus::OK => 'OK',
HTTPStatus::ACCESS_DENIED => 'Access Denied',
HTTPStatus::NOT_FOUND => 'Page Not Found',
};
}
}
this is like work-around to me...
With the way they are impelemented we will end-up with too much boilerplate code and possibility to forget to add values for every single method when adding new Enum. What will happen if I add case FORBIDDEN = 403
but forgot to add it's label in
static method getLabel
. And this become too much hassle when have 2-3 methods more to forget about.
They should be implemented like Java Enums. They are awesome.
public enum Element {
H("Hydrogen"),
HE("Helium"),
NE("Neon");
public final String label;
private Element(String label) {
this.label = label;
}
}
and then you just use label. So much shorter and simpler.
Element.H.label
@Warxcell technically Java, PHP 8.1 and this library's enums are the same thing. They can not be compared with constants enums because all these implementations uses singleton objects to represent enum's values
I see your point about boilerplate code. It is something that can be improved in future versions of PHP. Still, you won't be able to miss to put the label into getLabel() method because match
expression would not give you to make a mistake. You will get an error in runtime. Furthermore, such static analysis tools like Psalm can help you catch an error earlier.
To motivate you to use PHP 8.1 enums please review a problem with static method calls that I've described in README. IMO the benefit of using more convenient PHP 8.1 enums syntax compensate missing features.
Also, you will benefit from the fact that most of the libraries will support new enums out of the box.
This library currently does not have Doctrine integration. Doctrine type implementation can be inspired by https://github.com/acelaya/doctrine-enum-type