Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Nested foreach loops, both in php and smarty

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Smarty Development
View previous topic :: View next topic  
Author Message
timgno
Smarty Rookie


Joined: 12 Apr 2013
Posts: 6

PostPosted: Fri Apr 12, 2013 6:16 pm    Post subject: Nested foreach loops, both in php and smarty Reply with quote

Hello!

I have a problem with nested loops that do not give the desired result.

I show an example for you to understand ...

PHP:
Code:
foreach (array_keys($array) as $i)
         {             
            $arr['id'] = $i;             
                                $arr['name'] = $array[$i]->getVar('name');                                     
            $smarty->append('arr_list', $arr);             
                                unset($arr);
            // Get the list of tables
            $criteria = new Criteria();
                                // Database table results
            $criteria->add(new Criteria('table_arr', $i));
             
            $tables_arr = $tablesHandler->getAll($criteria);
            unset($criteria);
            // Display tables list               
            foreach (array_keys($tables_arr) as $t)
            {   
                  $table['id'] = $t;
                  $table['aid'] = $tables_arr[$t]->getVar('table_aid');         $smarty->assign('table', $table);             
                   unset($table);               
            }                                       
}


Smarty:
Code:
<{foreach item=arr from=$arr_list}>
         <tr class="head">
       <td class='center'><{$arr.id}></td>
            <td class='center'><{$arr.name}></td>
         </tr>
         <{foreach item=table from=$table}>
             <tr class="center">
               <td class='center'><{$table.id}></td>
                <td class='center'><{$table.name}></td>
             </tr>
         <{/foreach}>
     <{/foreach}>


Here is this code not the result that I have under the first cycle, which is the main one.

In practice I have as a result the loop father with a certain number of children in its specific cycle based on the results of the database in this case the tables. For each array must have its own specific number of tables.

I also tried with section but does not work the same.

Mainly because I did not use this work regularly with smarty templates, but I used all the html code along with php and then I used only the two php foreach loops.

I hope you find the right help.

Thank you!
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Fri Apr 12, 2013 8:16 pm    Post subject: Reply with quote

In this loop:

Code:
foreach (array_keys($tables_arr) as $t)
            {   
                  $table['id'] = $t;
                  $table['aid'] = $tables_arr[$t]->getVar('table_aid');         $smarty->assign('table', $table);             
                   unset($table);               
            }


You are writing over what gets assigned each iteration:

Code:
$smarty->assign('table', $table);


That might be part of the problem? Maybe something like:

Code:
foreach (array_keys($tables_arr) as $t)
            {   
                  $table['id'] = $t;
                  $table['aid'] = $tables_arr[$t]->getVar('table_aid');       
                  $tables[] = $table;
                  unset($table);               
         
            }
$smarty->assign('tables', $tables);   


Or, use $smarty->append() like in the outer loop.
Back to top
View user's profile Send private message Visit poster's website
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Fri Apr 12, 2013 10:28 pm    Post subject: Reply with quote

Another note:

in
Code:
         <{foreach item=table from=$table}>


you should not use for 'item' the same variable name (table) as the 'from' variable.

This could cause unexpected results.
Back to top
View user's profile Send private message
timgno
Smarty Rookie


Joined: 12 Apr 2013
Posts: 6

PostPosted: Sat Apr 13, 2013 12:10 am    Post subject: Reply with quote

Thank you for your reply but don't work in any way

Others solutions?
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Sat Apr 13, 2013 7:45 am    Post subject: Reply with quote

Now I see. You don't create a nested array.
The array table should be a sub array of arr. Right?

Code:
foreach (array_keys($array) as $i)
         {             
            $arr['id'] = $i;             
            $arr['name'] = $array[$i]->getVar('name');                                     

            // Get the list of tables
            $criteria = new Criteria();
            // Database table results
            $criteria->add(new Criteria('table_arr', $i));
             
            $tables_arr = $tablesHandler->getAll($criteria);
            unset($criteria);
            // Display tables list
           
            $tables = array();   
            foreach (array_keys($tables_arr) as $t)
            {   
                  $table['id'] = $t;
                  $table['aid'] = $tables_arr[$t]->getVar('table_aid');
                  $tables[] = $table;
            }
            // add table as nested subarray
            $arr['tables'] = $tables;                               
            $smarty->append('arr_list', $arr);             
            unset($arr);
}



Code:
{foreach item=arr from=$arr_list}>
         <tr class="head">
       <td class='center'><{$arr.id}></td>
            <td class='center'><{$arr.name}></td>
         </tr>
         <{foreach item=table from=$arr.tables}>
             <tr class="center">
               <td class='center'><{$table.id}></td>
                <td class='center'><{$table.name}></td>
             </tr>
         <{/foreach}>
<{/foreach}>
Back to top
View user's profile Send private message
timgno
Smarty Rookie


Joined: 12 Apr 2013
Posts: 6

PostPosted: Sat Apr 13, 2013 8:20 am    Post subject: Reply with quote

in this way the list is empty, I don't see anything even arr_list and tables.

order to function well, it is necessary to use assign for each cycle.

The real problem is that in this way see the lists of arr_list and tables, tables are the same number of arr_list1, arr_list2. etc ...

The result should be a nested array into another array with the following result:

Code:
Array {
      [1]->  Array List {
                                [1] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                                [2] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                                [3] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
      }
      [2]->  Array List {
                                [1] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                                [2] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                                [3] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                                [4] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                                [5] -> Array Tables {
                                                                [1] id
                                                                [2] name
                                                             }
                    }
}


I hope I explained myself better this time, otherwise I'll send you a pm with all the code is php and smarty

Thanks!
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Sat Apr 13, 2013 1:08 pm    Post subject: Reply with quote

Your old code did not create a nested array.
Mine does. Are you sure that you copied my code right?

Note that in PHP it does use two different variables: table and tables.

I just saw that table is not filled with index 'name' but you used in PHP index 'aid'. So something is wrog there.
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Mon Apr 22, 2013 12:48 pm    Post subject: Reply with quote

To begin with, you're doing it wrong from the very first line of your code. The construction

foreach(array_keys() ...)

implicitly create a new array, which takes additional time and memory.
To do it straight, you should have used construction

foreach($array as $i => $value)

this would also let you avoid loop hopping in line 4 - instead of

$arr['name'] = $array[$i]->getVar('name');

you could have used the straightforward

$arr['name'] = $value->getVar('name');
Back to top
View user's profile Send private message
timgno
Smarty Rookie


Joined: 12 Apr 2013
Posts: 6

PostPosted: Thu Apr 25, 2013 9:48 am    Post subject: Reply with quote

It is true!

But then I adopted another method to simplify, so I avoid to use a key useless:

Code:
$res = array();
$arr = $arr_handler->getObjects($criteria, true);
foreach (array_keys($arr) as $i) {
       $res['arr'][$i]['id'] = $arr[$i]->getVar('id');
       $res['arr'][$i]['name'] = $arr[$i]->getVar('name');
       $tables = $arr[$i]->tables();
       foreach($tables as $table){
                    $res['arr'][$i]['tables'][] = array('id' => $table['id'], 'name' => $table['name']);
       }
}
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Tue Apr 30, 2013 11:17 pm    Post subject: Reply with quote

/facepalm
Read your code, and my previous reply.
You're wasting an enormous amount of resources, and implying that you're doing it "better" way?
Back to top
View user's profile Send private message
timgno
Smarty Rookie


Joined: 12 Apr 2013
Posts: 6

PostPosted: Wed May 01, 2013 8:21 pm    Post subject: Reply with quote

And if I use
Code:
unset()
to free the memory for each cycle, so it does not use that much
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Thu May 02, 2013 1:29 pm    Post subject: Reply with quote

instead of this:

Code:
foreach (array_keys($arr) as $i) {


Do this:

Code:
foreach($arr as $i => $item) {


Then you can use $i as the index in the loop, and use $item instead of $arr[$i].
Back to top
View user's profile Send private message Visit poster's website
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Sat May 04, 2013 3:53 am    Post subject: Reply with quote

timgno wrote:
And if I use
Code:
unset()
to free the memory for each cycle, so it does not use that much

You making fool's work and claiming, that it isn't much because you're undoing what you did afterward?
Isn't that stupid? Why don't do it in first place, if you don't need to do it?
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Smarty Development All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP