Jump to content
Larry Ullman's Book Forums

Chapter 1 - Multidimentional Arrays


Recommended Posts

Hi Larry,

 

I have been playing around with the scripts in Chapter 1, but I am stumped as to how to achieve something.

 

I won't bore you with the end goal, but if I take the following from Script 1.3 (view_tasks.php).

while (list($task_id, $parent_id, $task) = mysqli_fetch_array($r, MYSQLI_NUM)) {

    // Add to the array:
    $tasks[$parent_id][$task_id] =  $task;

}

I want to add another variable (answer) that is going to change the array to look like this;

Array
                (
                    [parent_id] => Array
                        (
                            [task_id] => Array
                                (
                                    [task] => Test
                                    [answer] => Yes
                                )
                            [task_id] => Array
                                (
                                    [task] => New Test
                                    [answer] => No
                                )
                        )
                )

Step 1 - To achieve this, I have done the following. Is this correct?

while (list($task_id, $parent_id, $task) = mysqli_fetch_array($r, MYSQLI_NUM)) {

    // Add to the array:
    $tasks[$parent_id][$task_id] =  array ('task' => $task, 'answer' => $answer);
}

If it is, I am really stumped as to how to now change the function to echo the variables $task and $answer. I have been reading in the PHP manual, and trying different things, but ultimately I am completely lost. Your help would be much appreciated!

function make_list($parent, $all = null) {
    
    // Need the main $tasks array:
    
    static $tasks;
    
    if (isset($all)) {
        $tasks = $all;
    }
    
    echo '<ol>'; // Start an ordered list.
    
    // Loop through each subarray:
    foreach ($parent as $task_id => $todo) {
    
        // Display the item:
        echo "<li>$todo";
            
        // Check for subtasks:
        if (isset($tasks[$task_id])) {
            // Call this function again:
            make_list($tasks[$task_id]);
        }
            
        echo '</li>'; // Complete the list item.
    
    } // End of FOREACH loop.
    
    echo '</ol>'; // Close the ordered list.

} // End of make_list() function.

Regards

 

Jon

 

 

Link to comment
Share on other sites

For step 1, you need to return an answer value from the DB, which you're currently not doing.

I'm not sure what your query is, but if you modify that, then you should be able to return the answer value and store it in an $answer variable using "list" as follows:

while (list($task_id, $parent_id, $task, $answer) = mysqli_fetch_array($r, MYSQLI_NUM))

As for your main question, I'm not sure how you want to present the tasks and answers in your markup, but assuming $tasks[$task_id] is set, you can access individual tasks and answers as follows:

$tasks[$task_id]['task']
$tasks[$task_id]['answer']

In short, you need to use associative array syntax to access array elements when a string is used for an index.

If you look at the array you're assigning to each $tasks[$parent_id][$task_id] in your while loop, you're creating two new indexes called "tasks" and "answer".

 

If you were to change your array assignment as follows:

$tasks[$parent_id][$task_id] =  array ('a' => $task, 'b' => $answer);

Then you would access the task by writing $tasks[$task_id]['a'] and the answer by writing $tasks[$task_id]['b'].

That make sense?

Link to comment
Share on other sites

Hi HartleyStan,

 

Thanks.

 

The Step 1 part was just a typo on here, but good spot.

 

In the foreach part of the previously mentioned function, the value of the current element is set to $todo, then it can just be printed (essentially it is just printing $task).

    echo '<ol>'; // Start an ordered list.
    
    // Loop through each subarray:
    foreach ($parent as $task_id => $todo) {
    
        // Display the item:
        echo "<li>$todo";

I just want to do the same thing, which from your previous response would suggest I just need to echo $tasks[$task_id]['task']. That makes sense and is what I had tried earlier. However, I am just getting error's when I try to use it.

Notice: Array to string conversion in C:\xampp\htdocs\view_tasks.php on line 42 Array['task'].

 

I put this in place of $todo, should I be putting it somewhere else? I guess I am also confused about the whole foreach functionality now it is an associative array.... I don't know how setting the element to $todo can be used.

 

Regards

 

Jon

Link to comment
Share on other sites

Yeah, I think there is some confusion on your part, but I'm partially to blame, as I didn't explain things well.

Sorry.

 

Basically, for a foreach loop, the thing you loop through must be an array or an object.

The tricky thing though is when you have multidimensional arrays or other complex structures because the variable you assign each element in the array you're looping through can itself be a complex value, like an array or object.

 

For example, imagine the following array:

 

$arr = array(
  
  array('broccoli', 'carrots'),
  
  array('bananas', 'kiwi'),
  
  array('ham', 'beef')
  
);
 
If we run the following foreach loop:
 
foreach ($arr as $subarr) {

}
 
Then the $subarr variable will sequentially be set to each of the three subarrays in the $arr variable.
As such, you can't write just "echo $subarr" in the foreach loop or an error will occur.
 
Instead, you need to either put another loop within the foreach loop above, or you need to specify the index you want. For example:
 
foreach ($arr as $subarr) {
  
  echo $subarr[0] . ' ' . $subarr[1];
  
}
 
The same principle applies to your problem above.
Sometimes, when the array/object structure gets deep and complex, things can be tricky, but the same principles always apply.
 
If you're ever having issues trying to figure out the structure of a complex variable, I recommend putting the following in your code to help you debug everything:
 
echo '<pre>';

print_r($the_variable);

echo '</pre>';
 
Similarly, you can also use the var_dump function as necessary.
That answer your questions?
  • Upvote 1
Link to comment
Share on other sites

Thanks HartleySan, that did lead me to the answer I was looking for.

 

I just needed to change the original code from this;

        // Display the item:
        echo "<li>$todo";

To either this;

        // Display the item task:
        echo "<li>".$todo['task'];

Or this;

        // Display the item answer:
        echo "<li>".$todo['answer'];

I had tried this right at the beginning, but I had done the basic syntax wrong, I was trying to do this;

        // Display the item:
        echo "<li>$todo['answer']";

I clearly didn't pay attention to the error properly and I think that was why I was getting so confused about the whole thing! Started to doubt my fundamental understanding.

 

Cheers

 

Jon

  • Upvote 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...