-1

Let's say I have such query results. Originally they are absolutely flat rows (like MySQL query results always are) - I just managed to return them so that the current "main record" is unique and the rest is an array of related data.

But how to "convert" them all into hierarchical structure with php? Any good library etc?

As you see, fields of related data have alias names tablename:fieldname which helps to distinguish the tables of origin. The main data had original field names so it was easy to group the data by main records pk value.

OK, here is the data after the initial conversion. The final goal follows.

Array
(
    [1] => Array
        (
            [rowid] => 1
            [id] => 1
            [name] => Jalisco Philharmonic
            [related] => Array
                (
                    [0] => Array
                        (
                            [instruments:id] => 1
                            [instruments:type] => violin
                            [instruments:manufacturers_id] => 1
                            [instruments:orchestraId] => 1
                            [players:id] => 1
                            [players:name] => Aadu Vahtkumm
                            [players:instruments_id] => 1
                            [manufacturers:name] => Stradivari
                            [manufacturers:id] => 1
                            [conductors:id] => 1
                            [conductors:name] => Aadu Vahtkumm
                            [conductors:orchestraId] => 1
                        )

                    [1] => Array
                        (
                            [instruments:id] => 1
                            [instruments:type] => violin
                            [instruments:manufacturers_id] => 1
                            [instruments:orchestraId] => 1
                            [players:id] => 2
                            [players:name] => Leelo Luhvt
                            [players:instruments_id] => 1
                            [manufacturers:id] => 1
                            [manufacturers:name] => Stradivari
                            [conductors:id] => 1
                            [conductors:name] => Aadu Vahtkumm
                            [conductors:orchestraId] => 1
                        )

                    [2] => Array
                        (
                            [instruments:id] => 1
                            [instruments:type] => violin
                            [instruments:manufacturers_id] => 1
                            [instruments:orchestraId] => 1
                            [players:id] => 3
                            [players:name] => Valdur Voll
                            [players:instruments_id] => 1
                            [manufacturers:id] => 1
                            [manufacturers:name] => Stradivari
                            [conductors:id] => 1
                            [conductors:name] => Aadu Vahtkumm
                            [conductors:orchestraId] => 1
                        )

                    [3] => Array
                        (
                            [instruments:id] => 1
                            [instruments:type] => violin
                            [instruments:manufacturers_id] => 1
                            [instruments:orchestraId] => 1
                            [players:id] => 34
                            [players:name] => First Last
                            [players:instruments_id] => 1
                            [manufacturers:id] => 1
                            [manufacturers:name] => Stradivari
                            [conductors:id] => 1
                            [conductors:name] => Aadu Vahtkumm
                            [conductors:orchestraId] => 1
                        )                    
                )
        )
)

And the final expected goal looks like this. Some explanations: orchestra can have here many instruments and conductors. Instrument can have many players. But each instrument also have ("belongs to") a manufacturer.

Array
(
    [1] => Array
        (
            [rowid] => 1
            [id] => 1
            [name] => Jalisco Philharmonic
            [hasMany] => Array
                (
                    
                    [conductors] => Array
                        (
                            [id] => 1
                            [name] => Aadu Vahtkumm
                            [orchestraId] => 1
                        )
                    [instruments] => Array
                            [1] => Array
                                (
                                    [id] => 1
                                    [type] => violin
                                    [belongsTo] => Array
                                        (
                                            [manufacturers_id] => Array 
                                                (
                                                    [value] => 1,
                                                    [parentKey] => id,
                                                    [table] => manufacturers,
                                                    [data] => Array
                                                        (
                                                            [id] => 1
                                                            [name] => Stradivari
                                                        )
                                                ),
                                            [orchestraId] => Array 
                                                (
                                                    [value] => 1
                                                )
                                        ),
                                    [hasMany] => Array
                                        (
                                            [players] => Array
                                                (
                                                     [1] => Array
                                                        (
                                                            [id] => 1
                                                            [name] => Aadu Vahtkumm
                                                            [belongsTo] => Array
                                                                (
                                                                    [instruments_id] => Array
                                                                        (
                                                                            [value] => 1
                                                                        )
                                                                )
                                                        )
                                                    [2] => Array
                                                        (
                                                            [id] => 2
                                                            [name] => Leelo Luhvt
                                                            [belongsTo] => Array
                                                                (
                                                                    [instruments_id] => Array
                                                                        (
                                                                            [value] => 1
                                                                        )
                                                                )
                                                        )
                                                    [3] => Array
                                                        (
                                                            [id] => 3
                                                            [name] => Valdur Voll
                                                            [belongsTo] => Array
                                                                (
                                                                    [instruments_id] => Array
                                                                        (
                                                                            [value] => 1
                                                                        )
                                                                )

                                                        )
                                                    [34] => Array
                                                        (
                                                            [id] => 34
                                                            [name] => First Last
                                                            [belongsTo] => Array
                                                                (
                                                                    [instruments_id] => Array
                                                                        (
                                                                            [value] => 1
                                                                        )
                                                                )
                                                        )
                                               
                                               )
                                        )
                                )

                        )
        )
)

As @nnichols suggested

  1. example result as table view (I guess it will be too large)
rowid id name instruments:id instruments:type instruments:manufacturers_id instruments:orchestraId players:id players:name players:instruments_id manufacturers:name manufacturers:id conductors:id conductors:name conductors:orchestraId
1 1 Jalisco Philharmonic 1 violin 1 1 1 Aadu Vahtkumm 1 Stradivari 1 1 Aadu Vahtkumm 1
1 1 Jalisco Philharmonic 1 violin 1 1 2 Leelo Luhvt 1 Stradivari 1 1 Aadu Vahtkumm 1
1 1 Jalisco Philharmonic 1 violin 1 1 3 Valdur Voll 1 Stradivari 1 1 Aadu Vahtkumm 1
1 1 Jalisco Philharmonic 1 violin 1 1 34 First Last 1 Stradivari 1 1 Aadu Vahtkumm 1

And here is the code which made its initial grouping

$dataRows = [];
$mainRow = [];
while ($row = mysqli_fetch_assoc($result)) {
    $rowid = $row['rowid'];
    while (!strpos(key($row), ':')) {
        $mainRow[key($row)] = $row[key($row)];
        unset($row[key($row)]);
    }
    $mainRow['related'][] = $row;
    $dataRows[$rowid] = $mainRow;
}
echo json_encode($dataRows);

Here also tables and relations defined in json

{
  "instruments": {
    "pk": "id",
    "data": {},
    "belongsTo": {
      "orchestraId": {
        "parentKey": "id",
        "label": "name",
        "table": "orchestras"
      },
      "manufacturers_id": {
        "parentKey": "id",
        "label": "name",
        "table": "manufacturers"
      }
    }
  },
  "manufacturers": {
    "pk": "id",
    "label": "name",
    "data": {}
  },
  "orchestras": {
    "pk": "id",
    "data": {}
  },
  "conductors": {
    "pk": "id",
    "data": {},
    "belongsTo": {
      "orchestraId": {
        "parentKey": "id",
        "label": "name",
        "table": "orchestras"
      }
    }
  },
  "players": {
    "pk": "id",
    "data": {},
    "belongsTo": {
      "instruments_id": {
        "parentKey": "id",
        "label": "type",
        "table": "instruments"
      }
    }
  }
}

1 Answers1

0

I would advise against this approach but you could extend your existing logic to build it out manually -

$out = [];

while ($row = mysqli_fetch_assoc($result)) {
    $out[$row['rowid']]['rowid'] = $row['rowid'];
    $out[$row['rowid']]['id'] = $row['id'];
    $out[$row['rowid']]['name'] = $row['name'];

    $out[$row['rowid']]['hasMany']['conductors'][$row['conductors:id']]['id'] = $row['conductors:id'];
    $out[$row['rowid']]['hasMany']['conductors'][$row['conductors:id']]['name'] = $row['conductors:name'];
    $out[$row['rowid']]['hasMany']['conductors'][$row['conductors:id']]['orchestraId'] = $row['conductors:orchestraId'];

    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['id'] = $row['instruments:id'];
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['type'] = $row['instruments:type'];

    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['belongsTo']['manufacturers_id']['value'] = $row['instruments:manufacturers_id'];
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['belongsTo']['manufacturers_id']['parentKey'] = 'id';
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['belongsTo']['manufacturers_id']['table'] = 'manufacturers';
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['belongsTo']['manufacturers_id']['data']['id'] = $row['manufacturers:id'];
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['belongsTo']['manufacturers_id']['data']['name'] = $row['manufacturers:name'];
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['belongsTo']['orchestraId']['value'] = $row['id'];

    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['hasMany']['players'][$row['players:id']]['id'] = $row['players:id'];
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['hasMany']['players'][$row['players:id']]['name'] = $row['players:name'];
    $out[$row['rowid']]['hasMany']['instruments'][$row['instruments:id']]['hasMany']['players'][$row['players:id']]['belongsTo']['instrument_id']['value'] = $row['instruments:id'];
}

I would suggest doing some reading about Object Relational Mappers (ORMs) if you want to go down this route.

user1191247
  • 10,808
  • 2
  • 22
  • 32