dynamic rows and columns inside a foreach loop - php

I'm trying, but I'm stucked with the logic... so, I have this:
$max_items=10;
echo '<table>';
echo '<tr>';
foreach ($feed->get_items(0, $max_items) as $item):
echo '<td>';
echo $some_value;
echo '</td>';
endforeach;
echo '</tr>';
echo '</table>';
I want to show the results like this:
[1][2]
[3][4]
[5][6]
[7][8]
[9][10]
I have to use a while statement? A for loop? Inside or outside the foreach code?
I really don't get it...
Thanks for any kind of help

Here's a very simple example of how to do this sort of HTML building.
<?php
$data = range( 'a', 'z' );
$numCols = 2;
echo "<table>\n";
echo "\t<tr>\n";
foreach( $data as $i => $item )
{
if ( $i != 0 && $i++ % $numCols == 0 )
{
echo "\t</tr>\n\t<tr>\n";
}
echo "\t\t<td>$item</td>\n";
}
echo "\t</tr>\n";
echo '</table>';
This way, you can change $numCols to be 3 or 4 (or any number) and always see that number of columns in the output, and it does so without using an nested loop.

Take a look at this link to Displaying Recent Posts On a Non-WordPress Page. I think what you may be looking for is a way to loop over the objects get methods. For that you will need a nested loop and some sort of reflection.

I was just recently working with SimplePie on the February release of Cogenuity so this is still fresh in my mind.
Your $some_value variable never gets initialized.
The $item object will have such methods as get_permalink(), get_title(), get_description(), and get_date()

Related

Php count elements inside loop not outside

I know how to count elements inside a loop, but tried and can´t find a solution. Actually, I can count the elements in loop in this way:
$i = 0;
foreach ($Contents as $item)
{
$i++;
}
echo $i;
But in my case, I have large function and I can do this, but need more time for count elements inside. I can´t put the string for showing number elements inside loop outside of the function. I must show inside loop all number of elements and show as this. Here's an example:
$i = 0;
foreach ($Contents as $item)
{
print "Number Elements it´s : $i";
print "Element ".$i."<br>";
$i++;
}
The problem here is that the phrase "number elements it´s" always repeats, because inside loop, and all time $i show me 0,1,2,3,4,5 ...... and all time the same as number of elements inside loop.
My idea and question is if it´s possible inside loop to show the number of elements and after this show the elements as this structure when executing the script:
Númber elements it´s : 12
Element 1
Element 2
Element 3
.
.
.
.......
This it´s my question. I hope you understand it all. Thanks in advance.
As mentioned in the comments, youu will need to use the count() function for that. If you insist on having it inside the loop, simply do it like this:
$i = 0;
foreach ($Contents as $item)
{
if($i == 0) {
print "Number of Elements is : " . count($Contents) . "<br><br>";
}
print "Element ".$i."<br>";
$i++;
}

How to put to style two foreach statements output PHP

How do I put the first foreach statement's output in one column in a table and the other foreach statement's output in another column. I tried something but it put it all in one column for some reason. Here is my code:
<table border="0" align="center">
<?php
foreach($anchors as $a) {
$text = $a->nodeValue;
$href = $a->getAttribute('href');
$i++;
if ($i > 16) {
if (strpos($text, "by owner") === false) {
if (strpos($text, "map") === false) {
echo "<tr><td><a href =' ".$href." '>".$text."</a><br/></td></tr>";
}
}
}
foreach($span as $s) {
echo "<tr><td>".$s->nodeValue."</td></tr>";
}
}
?>
</table>
<tr></tr> marks a row. <td></td> marks a column. To make 2 columns, use just one set of <tr> tags per iteration, with two sets of <td></td>s between them.
That said, what exactly is $span? Does it contain the same number of elements as $anchors, and you want to display one item from each per row? If so you'll need to restructure your code a bit. There are several ways to do this—here's a simple way:
<table border="0" align="center">
<?php
$i = 0;
foreach($anchors as $a) {
echo "<tr>";
$text = $a->nodeValue;
$href = $a->getAttribute('href');
if ($i >= 16) {
if (strpos($text, "by owner") === false) {
if (strpos($text, "map") === false) {
echo "<td><a href =' ".$href." '>".$text."</a><br/></td>";
}
}
} else {
echo "<td></td>"; #output a blank cell in the first column
}
echo "<td>" . $span[$i]->nodeValue . "</td>";
echo "</tr>";
++$i
}
?>
</table>
EDIT: It looks like your $span is a DOMNodeList object, not an array. I don't have experience with this, but it looks like you can use the DOMNodelist::item function to get the current item in the list (see http://php.net/manual/en/domnodelist.item.php):
echo "<td>" . $span->item($i)->nodeValue . "</td>";
So try changing the respective line in my answer to that.
It is hard without an idea of the data, but something like this perhaps:
// start a table
echo '<table>';
// for as long as there are elements in both span and anchors
for ($i=0; $i < $anchors->length && $i < $span->length; $i++) {
// start a new table row
echo '<tr>';
// get the current span and anchor
$a = $anchors->item($i);
$s = $span->item($i);
// print them
$text = $a->nodeValue;
$href = $a->getAttribute('href');
// col 1, number
echo '<td>'.$i.'</td>';
// col 2, anchor
echo '<td>'.$text.'</td>';
// col 3, span
echo '<td>'.$s->nodeValue.'</td>';
// close the table row
echo '</tr>';
}
// close the table
echo '</table>';
(code not tested) It is difficult to be more specific without the actual data.
This uses the 'current' and 'next' built in to php.
A few hints/remarks/sidenotes that may help you on the way:
- Note that I used single quotes cause they are much better for
performance (double quotes will be interpreted by php).
- Try to use as little loops (for, while, foreach) as possible. They are a powerfull
tool, but can drain memory and performance quickly!
- Only nest loops if you are working with multiple dimensions (array inside array),
which is not the case here (I think)
- Try to limit the number of nested blocks (if inside if inside if inside loop). I try to go never deeper then 2 levels (which is not an absolute rule off course, just a good standard). If not possible create a function.
- Comment your code! I have difficulty understanding your code (and I write PHP daily for a living), and I can imagine you will to in a couple of weeks. Commenting may look like a waste of time, but it will ease debugging a lot, and is a blessing when updating your (or someone elses) code later on!
EDIT:
I just noticed you are not working with a DOMNodeList and not an array, so I updated my code. Should work fine, and a lot cleaner code imo. Like I said, hard without seeing the data...

Nested looping with an associative array of arrays, getting no output (PHP)

Thanks in advance for looking.
I am trying to build some HTML using a foreach loop with a few layers of arrays.
Groups of data and groups of titles for that data are stored in sets of arrays.
In turn, those arrays of data are stored in an array ($titlegroups and datagroups).
The aim being to set up a nested loop, where each group of data and titles populate the relevant fields in some html.
Here is a full set of code (structure) of my attempt.
$a=1;
$b=2;
$c=3;
$d=4;
$titlesA=array('string1','string2');
$titlesB=array('string3','string4');
$dataA=array($a,$b);
$dataB=array($c,$d);
$titlegroups=array($titlesA,$titlesB);
$datagroups=array($dataA,$dataB);
$groups=array(array_combine($titlegroups, $datagroups));
$j=0;
foreach($groups as $titlesX => $dataX)
{
$j++;
echo'<div class="something">';
$i=0;
foreach(array_combine($titlesX, $dataX) as $title => $var)
{
$i++;
echo '
<li>'.$title.'</li><input name="'.$j.'x'.$i.'" value="'.$var.'" />
';
}
echo '</div>';
}
Checking it in ideone I get the error:
Warning: array_combine() expects parameter 1 to be array, integer
given in /home/0zw0mb/prog.php on line 26
Line 26 is:
foreach(array_combine($titlesX, $dataX) as $title => $var)
but $titlesX and $dataX should both be arrays?
If anyone can set me straight I'd appreciate it. Thanks.
You can't have arrays as keys, they are converted to strings. You logic required some changes and an additional sentinel variable ($idx), to tell when the code crosses one group to another.
array_merge was necessary due to the key requirements of arrays.
Check the below code:
$a=1;
$b=2;
$c=3;
$d=4;
$titlesA=array('string1','string2');
$titlesB=array('string3','string4');
$dataA=array($a,$b);
$dataB=array($c,$d);
$titlegroups=array_merge($titlesA,$titlesB);
$datagroups=array_merge($dataA,$dataB);
$items=array_combine($titlegroups, $datagroups);
$indexes = array(count($dataA), count($dataB));
$i = 0;
$j = 0;
$idx = $indexes[$j];
echo '<div class="something">';
foreach($items as $title => $var)
{
echo '
<li>'.$title.'</li><input name="'.$j.'x'.($i++).'" value="'.$var.'" />
';
$idx--;
if ($idx == 0) {
/* End of a group */
echo '</div>';
$idx = $indexes[++$j];
/* If there is another group, create new container */
if ($idx != null) {
echo '<div class="something">';
}
}
}

Count results inside foreach then store that value in a variable to be used elsewhere

How do you count the results inside a foreach then store that value in a variable to be used on another foreach.
Example. This foreach returns 5 items
foreach ($xml->items as $item) {
echo "$item->name";
echo "$item->address";
}
Now I want that the foreach above be counted and stored in say $totalitems and be used on another foreach. This second foreach also counts its results and store in $totalitems2. Something like this:
foreach ($xml->items as $item) { //Same source but they will be displayed separately based on a condition.
echo "$item->name";
echo "$item->address";
if_blah_blah_meet_condition_then_break;
}
So basically what I want here is to restrict the total number of items being displayed on both foreach combined. $totalitems and $totalitems2 should have the sum of 8. 8 is the number I want limit the items returned. Doesn't matter if the other foreach has more items than the other. 3 and 5. 4 and 4. 6 and 2. Etc.
How can I achieve this? Please advice.
Just use the simple iterator ++ methods. When you are on the second foreach, watch for when $i passes the number that you want to stop it.
Code:
$i = 0;
foreach ($xml->items as $item) {
echo "$item->name";
echo "$item->address";
$i++;
}
foreach ($xml->items as $item) {
echo "$item->name";
echo "$item->address";
$i++;
if ($i > 5) { // or whatever the number is
break;
}
}
$totalItems = count($xml->items);
foreach ($xml->items as $item) {
echo "$item->name";
echo "$item->address";
}
Just use count($xml->items) and that value in the condition, inside the loop.
It seems your array is stored in xml->items therefor, you only would have to save it in another variable if you want to store it.
foreach ($xml->items as $cont=>$item) {
echo "$item->name";
echo "$item->address";
if($cont<8){
$totalItems_one[] = $item;
}
}
//whatever changes you do to $xml->items
foreach ($xml->items as $cont=>$item) {
echo "$item->name";
echo "$item->address";
if($cont<8){
$totalItems_two[] = $item;
}
}
Like this you have the two new arrays totalItems_one and totalItems_two and you can get the number of items just doing count($totalItems_one) or count($totalItems_two) whenever you want.

PHP : how to use foreach loop inside an echo statement?

i am tring to put a loop to echo a number inside an echo ;
and i tried as bellow :
$array = array();
$result = mysql_query("SHOW TABLES FROM `st_db_1`");
while($row = mysql_fetch_row($result) ){
$result_tb = mysql_query("SELECT id FROM $row[0] LIMIT 1");
$row_tb=mysql_fetch_array($result_tb);
$array[] = $row[0];
$array2[] = $row_tb[0];
//checking for availbility of result_tb
/* if (!$result_tb) {
echo "DB Error, could not list tablesn";
echo 'MySQL Error: ' . mysql_error();
exit;
} */
}
natsort($array);
natsort($array2);
foreach ($array as $item[0] ) {
echo "<a href=show_cls_db.php?id= foreach ($array2 as $item2[0]){echo \"$item2[0]\"}>{$item[0]}<br/><a/>" ;
}
but php is not considering foreach loop inside that echo ;
please suggest me something
As mentioned by others, you cannot do loops inside a string. What you are trying to do can be achieved like this:
foreach ($array as $element) {
echo "<a href='show_cls_db.php?id=" . implode('', $array2) . "'>{$element}</a><br/>";
}
implode(...) concatenates all values of the array, with a separator, which can be an empty string too.
Notes:
I think you want <br /> outside of <a>...</a>
I don't see why you would want to used $item[0] as a temporary storage for traverser array elements (hence renamed to $element)
Just use implode instead of trying to loop the array,
foreach ($array as $item)
{
echo implode("",$array2);
}
other wise if you need to do other logic for each variable then you can do something like so:
foreach ($array as $item)
{
echo '<a href="show_details.php?';
foreach($something as $something_else)
{
echo $something_else;
}
echo '">Value</a>';
}
we would have to see the contents of the variables to understand what your trying to do.
As a wild guess I would think your array look's like:
array(
id => value
)
And as you was trying to access [0] within the value produced by the initial foreach, you might be trying to get the key and value separate, try something like this:
foreach($array as $id => $value)
{
echo $id; //This should be the index
echo $value; //This should be the value
}
foreach ($array as $item ) {
echo "<a href=\"show_cls_db.php?id=";
foreach ($array2 as $item2) { echo $item2[0]; }
echo "\">{$item[0]}<br/><a/>" ;
}
No offense but this code is... rough. Post it on codereview.stackexchange.com for some help re-factoring it. A quick tip for now would be to use PDO, and at the least, escape your inputs.
Anyway, as the answers have pointed out, you have simply echoed out a string with the "foreach" code inside it. Take it out of the string. I would probably use implode as RobertPitt suggested. Consider sorting and selecting your data from your database more efficiently by having mysql do the sorting. Don't use as $item[0] as that makes absolutely no sense at all. Name your variables clearly. Additionally, your href tag is malformed - you may not see the correct results even when you pull the foreach loop out of the echo, as your browser may render it all away. Make sure to put those quotes where they should be.

Categories