0

I'am working in CodeIgniter (CI), and trying to create a nested set of category items for a dropdown list. To create a dropdown box, in CI you need to echo form_dropdown('name', $array, $selectedID).

Here is my function to create a nested list array:

$categoryData = array();
function list_categories($cats, $sub = ''){
    foreach($cats as $cat){

        //$cat['category']->id = $sub.$cat['category']->title;
        $categoryData[$cat['category']->id] = $sub.$cat['category']->title;

        if( sizeof($cat['children']) > 0 ){
            $sub2 = str_replace('—→ ', '–', $sub);
            $sub2.= '–→ ';
            list_categories($cat['children'], $sub2);
        }
    }
}

If I will do a var_dump($categoryData); just right after the foreach inside the list_categories() function, it will return the array of nested sets. So this is ok when using var_dump() inside the function. But I need to do this:

<?php
    list_categories($categories);
    var_dump($categoryData);
?>

And here i get an empty array, here is an output:

array (size=0)
  empty

Could someone tell me what I'am doing wrong here ?

aspirinemaga
  • 3,753
  • 10
  • 52
  • 95
  • Your function isn't returning anything. Put `$categoryData = array();` into the first line of the function, and add `return $categoryData` at the end of the function. Also, you're not assigning `list_categories()` to anything when you call it: `$categoryData = list_categories($categories);` – billyonecan May 15 '13 at 07:08
  • Even if I do at the end of the function `return $categoryData;`, it still be empty where I'am doing a `var_dump()`. Do you know why ? – aspirinemaga May 15 '13 at 07:10
  • @aspirinemaga , updated. Please, consider. – BlitZ May 15 '13 at 07:28

2 Answers2

3

Your function modifies local copy, which should be returned to global scope. What you want to achieve might be done with globals ("bad practice"), return or references.

Try to use references:

function list_categories(&$result, $cats, $sub = ''){    // <- THIS
    foreach($cats as $cat){

        //$cat['category']->id = $sub.$cat['category']->title;
        $result[$cat['category']->id] = $sub.$cat['category']->title; // <- THIS

        if( sizeof($cat['children']) > 0 ){
            $sub2 = str_replace('&mdash;&rarr;&nbsp;', '&ndash;', $sub);
            $sub2.= '&ndash;&rarr;&nbsp;';

            list_categories($result, $cat['children'], $sub2); // <- THIS
        }
    }
}

$categoryData = array();

list_categories($categoryData, $categories); // <- THIS

UPD: In the end, for recusive function, references are better (as for me). Sorry for the inconvinience.

BlitZ
  • 12,038
  • 3
  • 49
  • 68
  • I tested it out, once you added your answer, and it output only the last array. If you relook into the foreach statement, you will notice that it goes deeper and deeper, so by creating multiarrays inside the arrays. Any idea? BTW I could test it tonight, and will give you my feedback.Thank you for your post – aspirinemaga May 15 '13 at 07:55
  • @aspirinemaga it's currently should be recursive. I've misread question first time. – BlitZ May 15 '13 at 07:59
0

you should:

function list_categories($cats, $sub = ''){
global $categoryData;  // add this

If you do not, function does not see the global $categoryData and creates a local one instead. which it does not return.

Note that, minimal use of global variables is recommended for avoiding spagetthi code.

Volkan
  • 2,212
  • 1
  • 14
  • 14
  • I read somewhere in `PHP security` that using `global ...` is not recommended. Isn't it applying to a function ? – aspirinemaga May 15 '13 at 07:14
  • 2
    @aspirinemaga it is not a security issue. It's "bad" in "wrong hands". – BlitZ May 15 '13 at 07:15
  • @aspirinemaga , also check out [this](http://stackoverflow.com/questions/16054279/passing-a-variable-to-its-parent-function-in-php). It might be applied to the global scope too. – BlitZ May 15 '13 at 07:18