Skip to content

PHP Arrays vs. DTO READ models / VIEW collections using Doctrine #16

@webdevilopers

Description

@webdevilopers

Currently I'm using PHP Arrays for single READ models. Actually it was a performance driven decision since I use them for exporting 100s of rows into a generated PDF.

But looks like this myth has been busted or at least is no longer regarded "relevant" since PHP_7_:

Looking at some DDD repository examples Java and DotNET write results coming from a persistence storage into a collection of objects.

Mostly these objects are then serializable to deliver primitive types like Command DTOs.

Currently I'm using the Doctrine Array hydration to handle a more complex query:

        $qb->select(array(
                'b.id',
                'b.date',
                'b.shift',
                'b.shippingnumber AS shipping_number',
                'GroupConcat(DISTINCT b.comment) AS comment',
                'SUM(b.customFieldNum1) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS custom_field_num_1',
                'SUM(b.customFieldNum2) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS custom_field_num_2',
                'SUM(b.customFieldNum3) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS custom_field_num_3',
                'SUM(b.customFieldNum4) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS custom_field_num_4',
                'SUM(b.customFieldNum5) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS custom_field_num_5',
                'b.customFieldStr1 AS custom_field_str_1',
                'b.customFieldStr2 AS custom_field_str_2',
                'b.customFieldStr3 AS custom_field_str_3',
                'b.customFieldStr4 AS custom_field_str_4',
                'b.customFieldStr5 AS custom_field_str_5',
                'p.id AS parttype_id',
                'p.integratorNumber AS part_number',
                'l.name AS location',
                'SUM(bps_ok.quantity) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS ok_total',
                'SUM(bps_ok.quantity+bps_nok_processed.quantity+bps_nok_blocked.quantity) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS total',
                'SUM(bps_nok_processed.quantity+bps_nok_blocked.quantity) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS nok_total',
                'SUM(bps_nok_processed.quantity) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS nok_processed',
                'SUM(bps_nok_blocked.quantity) / CASE WHEN COUNT(bps_ok.id) = 0 THEN 1 ELSE COUNT(bps_ok.id) / COUNT(DISTINCT bps_ok.id) AS nok_blocked',
            ))

Since Doctrine 2.4 it is possible to directly write a result into a DTO:

<?php
class CustomerDetails
{
    public function __construct($name, $email, $city, $value = null)
    {
        // Bind values to the object properties.
    }
}

<?php
$query = $em->createQuery('SELECT NEW CustomerDetails(c.name, e.email, a.city) FROM Customer c JOIN c.email e JOIN c.address a');
$users = $query->getResult(); // array of CustomerDetails

This works for any PHP class / POPO. While using ResultSetMapping only seems to work with Doctrine Entities:

What are your experiences / favorited strategies?

Related:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions