phparraysmultidimensional-array

Making a nested array in php


Probably my question is too much common or easy for you, but I really have no idea how to do it. Trying all everything I know and lots of googling didn't help me.

I just need a nested array.

Here is my PHP code:

EDITED
Corrected: $data['product_names'][$language['language_id']][] = array(

$data['product_names'] = array();

foreach ($data['languages'] as $language) {
    $product_names_info = $this->model_catalog_category->getCategoryMultiLang($this->request->get['product_id'], $language['language_id']);

    if ($product_names_info) {
        $data['product_names'][$language['language_id']][] = array(
            'category_id' => $product_names_info['category_id'],
            'language_id' => $product_names_info['language_id'],
            'name'        => $product_names_info['name']
        );
    }
}

print_r($data['product_names']);

The result that I get:

Array
(
    [5] => Array
        (
            [0] => Array
                (
                    [category_id] => 
                    [language_id] => 
                    [name] => 
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [category_id] => 
                    [language_id] => 
                    [name] => 
                )

        )

    [4] => Array
        (
            [0] => Array
                (
                    [category_id] => 
                    [language_id] => 
                    [name] => 
                )

        )

    ... 

The result should look like this:

Array
(
    [0] => Array
        (
            [language_id] => 1
            [category_id] => 8
            [name] => book
        )

    [1] => Array
        (
            [language_id] => 5
            [category_id] => 188
            [name] => magazine
        )

...
)
Array
(
    [0] => Array
        (
            [language_id] => 1
            [category_id] => 8
            [name] => buch
        )

...

UPDATED
The result of print_r($product_names_info); inside foreach ($data['languages'] as $key => $language) {

Array
(
    [0] => Array
        (
            [language_id] => 5
            [category_id] => 8
            [name] => Gecelik
        )

    [1] => Array
        (
            [language_id] => 5
            [category_id] => 188
            [name] => Sabahlık
        )

    ...

)
Array
(
    [0] => Array
        (
            [language_id] => 2
            [category_id] => 8
            [name] => لباس خواب
        )

    [1] => Array
        (
            [language_id] => 2
            [category_id] => 188
            [name] => Sabahlık
        )

Thanks for any kind help.


Solution

  • Option 1:

    $data['product_names'] = [];
    
    foreach ($data['languages'] as $language) {
        $languageId = (int) $language['language_id'];
    
        // Fetch once per language
        $rows = $this->model_catalog_category
            ->getCategoryMultiLang(
                (int) $this->request->get['product_id'],
                $languageId
            );
    
        if (empty($rows)) {
            continue; // skip empty results early
        }
    
        // Direct assignment instead of pushing in nested loop
        $data['product_names'][$languageId] = array_map(
            static function ($row) {
                return [
                    'category_id' => $row['category_id'],
                    'language_id' => $row['language_id'],
                    'name'        => $row['name'],
                ];
            },
            $rows
        );
    }
    
    print_r($data['product_names']);
    /*
    Before: O(L × N)
    After: O(L × N) (same big-O, lower constant cost)
    
    Same O(L × N)
    But:
    Fewer intermediate array operations
    No repeated [] pushes
    Cleaner memory allocation
    */
    

    I think you were missing foreach for the data you fetched into var $product_names_info


    Option 2:

    If you want maximum performance

    If getCategoryMultiLang() can be changed, best possible solution is:

    Fetch everything in ONE query

    $results = $this->model_catalog_category
        ->getCategoryMultiLangForAllLanguages($productId);
    
    foreach ($results as $row) {
        $data['product_names'][$row['language_id']][] = [
            'category_id' => $row['category_id'],
            'language_id' => $row['language_id'],
            'name'        => $row['name'],
        ];
    }
    

    DB calls reduced from L → 1
    Biggest real-world performance win.