View previous topic :: View next topic |
Author |
Message |
timgno Smarty Rookie
Joined: 12 Apr 2013 Posts: 6
|
Posted: Fri Apr 12, 2013 6:16 pm Post subject: Nested foreach loops, both in php and smarty |
|
|
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 |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Fri Apr 12, 2013 8:16 pm Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Fri Apr 12, 2013 10:28 pm Post subject: |
|
|
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 |
|
timgno Smarty Rookie
Joined: 12 Apr 2013 Posts: 6
|
Posted: Sat Apr 13, 2013 12:10 am Post subject: |
|
|
Thank you for your reply but don't work in any way
Others solutions? |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Sat Apr 13, 2013 7:45 am Post subject: |
|
|
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 |
|
timgno Smarty Rookie
Joined: 12 Apr 2013 Posts: 6
|
Posted: Sat Apr 13, 2013 8:20 am Post subject: |
|
|
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 |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Sat Apr 13, 2013 1:08 pm Post subject: |
|
|
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 |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon Apr 22, 2013 12:48 pm Post subject: |
|
|
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 |
|
timgno Smarty Rookie
Joined: 12 Apr 2013 Posts: 6
|
Posted: Thu Apr 25, 2013 9:48 am Post subject: |
|
|
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 |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Tue Apr 30, 2013 11:17 pm Post subject: |
|
|
/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 |
|
timgno Smarty Rookie
Joined: 12 Apr 2013 Posts: 6
|
Posted: Wed May 01, 2013 8:21 pm Post subject: |
|
|
And if I use to free the memory for each cycle, so it does not use that much |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Thu May 02, 2013 1:29 pm Post subject: |
|
|
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 |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Sat May 04, 2013 3:53 am Post subject: |
|
|
timgno wrote: | And if I use 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 |
|
|