-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor type system #2841
Comments
In light of the need to have so-called parameterized types, this seems wrong. If we are going that way, the type registry should look more like a PSR-11 container (which it does already). FQCNs could still be used to identify types by default, but one should be able to have a type called |
TBH, just register EDIT: to be clear, being able to have a |
Oh yes, that second one sounds like a great idea, it would make it easier for static analysis tools to get make sense of the output of the type registry! So |
Right, so: /** @template-extends SomeEnum<Country> */
class MyCountryEnum extends SomeEnum
{
// ...
} therefore you would register it as |
Ah sorry, I should have made it a bit more obvious that I was referring to PHP 8 enums It would look more like this: <?php
enum MyProject\Country
{
// …
}
/**
* @template E of enum-string
*/
class Doctrine\DBAL\Types\Enum
{
/** @param E $enum */
public function __construct(string $enum)
{
// ...
}
/** @return E */
public function convertToPHPValue()
{
}
} Then you'd be able to register |
IMO just subclass and provide I just had an exact problem around custom names today: /** @Column(type="some_custom_thing") */ Then proceed to have Better: /** @Column(type=MySpecificDomainType::class) */ This removes ambiguity, and allows using tools like https://github.com/qossmic/deptrac on your system, preventing usage of DBAL types unknown to the current namespace (where not allowed). If it is static, declare it static, and use a class name. I would totally be for random strings if a PSR-11 container was used instead, but it isn't the case. |
If I have 10 enums, won't that mean 10 classes with very similar code? Won't that get old real fast?
Make sure you write your memoir someday 😄
Well maybe this could be considered. We're not far from it: dbal/src/Types/TypeRegistry.php Lines 59 to 65 in 1879160
dbal/src/Types/TypeRegistry.php Lines 29 to 41 in 1879160
|
No, usually just a class with no body suffices: /** @template-extends SomeEnumType<Country> */
final class MyCountryEnumType extends SomeEnumType
{
// literally nothing here
} |
Ok, so the code resides in |
Good point - indeed need to configure an enum reference or such 🤔 Probably: /** @template-extends SomeEnumType<Country> */
final class MyCountryEnumType extends SomeEnumType
{
public function __construct() {
parent::__construct(Country::class);
}
} |
Yes, and we're back to square one: types cannot be parameterized yet. Maybe I should open another RFC just for that. |
@greg0ire that is parametrized? |
No I meant |
This will still require us to write another (even if simple) class for every enum. That classes would be really repetitive, boring and provide no real value except from being workaround for not supporting type parametrization in DBAL / Doctrine as a whole. Not to mention that this solution would be only really viable for cases when one parameter is required, like with enums. If for example I would want to have "encrypted" type, which can accept |
The type is parametrized: you register an actual instance of it. As for repetition: it's still a degree safer than what we had before, which is a registry of strings of unknown shape => shape is now known and well defined.
If the flyweight pattern is to be perpetuated around DBAL types, then there's no solution in sight for that anyway. |
I wonder how important it is to perpetuate that pattern. |
Probably not much, since PHP's memory usage is not such a huge problem as per PHP 7.0 (and this stuff was designed for 5.2.x and then 5.3.x). The breakage would be ginormous, but having the That opens the door for people to provide their own |
@Ocramius it's unclear to me how having the It's also unclear to me what consequences lifting the "flyweight" restriction would have… do you see any there any? I understand that restriction as follows:
|
Hi, I've created a PR which would allow to automatically register all child class (enum) type names by registering their parent class (enum) type name. Then it would be possible to implement one EnumType, register it for BackedEnum type name and it would be automatically used for any backed enum. See the example implementation here: #5147 |
@greg0ire Just to give some food for thought on this topic. We use a specific type that deserialize json into a given object in the Similar to the mechanics of https://github.com/goodwix/doctrine-json-odm. What we would like to achieve from a consumer perspective is this: class Foo
public function __construct(
#[ORM\Column(type: new JsonSerializeType(Bar::class, serializationContext: [])]
private Collection $bars,
) {
} Or even better class Foo
public function __construct(
/**
* @param Collection<Bar>
*/
#[ORM\Column(type: new JsonSerializeType(serializationContext: [])
private Collection $bars,
) {
} That would require to have the Not sure if it's out of the scope of what has been described here and sorry it's not the case. |
I think it's in scope. For me the next step towards that would be this: #5036 |
@greg0ire |
No plan AFAIK, and I don't think it's in scope of this issue, which is about providing a more powerful type system, not more powerful types. |
Thanks for the quick answer 😄 I see the debate. But isn't it overkill to use a varchar(255) to store values that rarely exceed 10 characters? #[Column]
private MyEnum $myEnum; |
It is overkill yes: it takes more space than necessary. |
Goals
Todo
From @Majkl578 on slack:
just a quick thought of a possible approach:
Type
ToTypeRegistry
in favor of using theTypeRegistry
directly.My thoughts:
Instead of introducing an ISP-violating
TypeInterface
rightaway, split it from the start into small interfaces, which should makecanRequireSQLConversion
andrequiresSQLCommentHint
irrelevant. Here is such an interface, please give me some feedback. Also, get rid of the methods that we do not really need like __toString or (getName
)The text was updated successfully, but these errors were encountered: