doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.91k stars 2.5k forks source link

DQL NEW Operator to support PHP 8.x named arguments. #9182

Open acirulis opened 2 years ago

acirulis commented 2 years ago

Feature Request

Q A
New Feature yes
RFC no
BC Break no

Summary

Would it be possible for DQL NEW operator (https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/dql-doctrine-query-language.html#new-operator-syntax) to support PHP 8.0 named arguments (https://stitcher.io/blog/php-8-named-arguments) additionally to regular positional ones? As far as I see, DQL NEW() syntax is great for transforming Doctrine results to DTO objects but only drawback is use of positional arguments, which can be easily mixed up in the long-term (human error). Named arguments would fix that.

Consider class:

class BookDTO
{
    public function __construct(
        public int $id,
        public string $title,
        public int $publish_year,
    ) { }
}

Current DQL:

$query = $em->createQuery('SELECT NEW BookDTO(b.id, b.name, b.publish_year) FROM Book b');

Proposed DQL:

$query = $em->createQuery('SELECT NEW BookDTO(id: b.id, name: b.name, publish_year: b.publish_year) FROM Book b');

acirulis commented 2 years ago

Short update: I`ve found since that DQL NEW keyword has limitations ("Note that you can only pass scalar expressions to the constructor.") and figured better following approach for instantiating DTOs with array_map():

        $queryBuilder
            ->select('p', 'c')
            ->from(Person::class, 'p')
            ->leftJoin('p.contacts', 'c');

        return array_map(
            function (array $result) {
                return CustomerDto::createFromArray($result);
            },
            $queryBuilder->getQuery()->getArrayResult()
        );