mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Parameters for value conversion in Doctrine types #7280
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @janopae on GitHub (Dec 14, 2023).
Feature Request
Summary
While there are general options that you can provide to the
getSQLDeclarationpart of a Doctrine type, you can't provide any parameters to the conversion of values (from and to database values). The only way of parameterising the data conversion is subclassing the doctrine type.This sometimes leads to a lot of Doctrine type subclasses for very specific cases, which all have to be registered, both in production code and in tests. For parameters like number or string values which are specific for one entity, I hope you understand that subclassing really doesn't feel like the right approach.
This could be solved by passing parameters to the conversion methods. One rather simple way of doing this would be passing the options as a third parameter to
convertToDatabaseValueandconvertToPHPValue. As additional parameters passed to a PHP function are just ignored, this wouldn't even be a BC break.Example
Consider the following type, which wraps entity IDs in value objects:
If the reason you want to use Value Objects is that you want to prevent confusing ID values of different entities with one another, you need to subclass this for every entity, so each entity can have its own Value Object class.
If
convertToDatabaseValueandconvertToPHPValuegot a third options parameter, this wouldn't be necessary – instead, you could just use it as follows:You could pretty much use parameters for any type of value object which can be created in multiple specific ways.
Some other general examples could be a
MoneyType, which has acurrencyparameter (if all database values of an entity are saved in the same currency) or aLimitedHtmlType, which gets hydrated to a value object that escapes all HTML tags except a small list of allowed ones.@mpdude commented on GitHub (Jan 15, 2024):
Types are a concept of doctrine/dbal, not doctrine/orm. I am not so familiar with that, so take my explanations with a grain of salt. Maybe @morozov can amend or correct me.From the DBAL point of view, you bind values to query parameters, optionally specifiying a type. That means you'd need to provide the "general options" you're referring to at the time you're binding values to parameters. This is probably not what you want. I don't see how DBAL could otherwise get hold of the right type "extra parameters" to use. This is probably why, on the DBAL side of things,
Types are designed in this static way, without parameterization.When the ORM builds queries based on DQL expressions, it knows what entity classes and fields you refer to, and it can look up
@Columndefinitions in its class metadata. But there is no way to pass it on to DBAL type bindings.@antman3351 commented on GitHub (Jan 15, 2024):
Even just having options for
convertToPHPValuewould be a great improvement would that be possible? I could only find it being used byConnection::convertToPHPValuein the dbal folder@janopae commented on GitHub (Jan 15, 2024):
Why not?
If you have to repeat type declarations for every query, that doesn't get worse with paremeterised types. Repeatedly writing
setParameter($car, IdType::class, [Car::class])when binding query parameters is not much worse than repeatedly writingsetParameter($car, CarIdType::class);.EDIT: Updated pseudo-syntax to something more realistic.
@greg0ire commented on GitHub (Jan 15, 2024):
We plan to release DBAL 4 soon, and I think this might help: https://github.com/doctrine/dbal/pull/5036
@mpdude commented on GitHub (Jan 15, 2024):
How/when does DBAL use types to convert database to PHP values? Do you need to provide the types for columns when iterating result arrays/rows?
@mpdude commented on GitHub (Jan 15, 2024):
@greg0ire I may be mistaken, but the PR you referenced allows registering different instances of the same type under different names? That allows passing parameters to the type constructor.
I think what was requested here is a tad more dynamic, with the parameters being options declared on the ORM fields where the type is used.
@greg0ire commented on GitHub (Jan 15, 2024):
Yes, it would only be a workaround as it only addresses this point:
@antman3351 commented on GitHub (Jan 24, 2024):
To go any further with the discussion this needs to be answered.
I never use DBAL on it's own, I always use the ORM so I probably doing it wrong, but I couldn't get the DBAL to convert the built in types for a select query 🤔
created_at is type datetime, but in the result it's a stirng ( using MariaDB )