How to control foreach loop iteration in php - php

I want to fetch some data from database in the form of list. Following is my loop:
<div class="col-sm-4">
<ul>
<?php
foreach($subjects as $s)
{
echo "<li>$s->subject_title</li>";
}
?>
</u>
</div>
Now this loop prints data in one column and the user have to scroll down to view the last elements. I want to control the loop in such a way that after printing first 10 elements, it must start again from the div tag and print the next 10 elements and so on. I want to show the data in such a way that the user don't have to scroll down.
For example, I want to print the data in the following way:
I write the following code but it is not working. The div tag is only applied to the first 10 elements, and not on the rest of the data.
<div class="col-sm-6">
<ul class="filter-list">
<?php
$i = 0;
foreach($main_subjs as $i=>$ms)
{
if($i == 10) {
echo "</ul></div><div class='col-sm-6'><ul>";
$i++;
continue;
}
echo "<li><a href='#'>$ms->mains_title</a></li>";
}
?>
</ul>
</div>
Please Help.

As an arugment for a loop you can also use the key of array
foreach($subjects as $i=>$s)
When you will be able to "control" your loop, e.g.:
<div>
<?php
foreach($subjects as $i=>$s) {
if($i> 0 && $i % 5 == 0) {
echo "</div><div>";
}
echo "<li>$s->subject_title</li>";
}
?>
</div>

Related

how to put div in a for loop

For parsing a list of articles, i have this code to parse all the articles:
while($article = $articles->fetch())
{
$date = strtotime($article['createdAt']);
$formatted_date = date("F Y",$date);
?>
<br />
<div class="news-content">
<div class="news-image">
<?php echo $article['title']; ?>
</div>
<div class="news-article">
<h3>
<span><?php $date = strtotime($article['createdAt']); echo /*date("F j",$date);*/ strftime('%e %B',$date) ?></span>
<br />
<?php echo $article['title']; ?>
</h3>
</div>
</div>
<?php
} //end while loop
?>
What i want to achieve: only the first 5 <div class="news-content">...</div> should be shown.
I know i have to do something with a for loop
but i do not know exactly how to use the for loop for this situation...
Can someone help me with that?
There are a lot of different ways to limit a loop. One possibility is to use a for loop instead of a while loop. for is often a good option if you want something to happen a specific number of times. Adding something else like fetch into the continuation condition will mean it happens up to a specific number of times.
for ($i = 0; $i < 5 && $article = $articles->fetch(); $i++) {
// output article
}

foreach loop how to expect first result? [duplicate]

This question already has answers here:
PHP How to determine the first and last iteration in a foreach loop?
(21 answers)
Closed 7 years ago.
Using codeigniter framework i have this code here
<?php
foreach ($allposts as $posts) {
echo '<div class="col-sm-1">
<div class="thumbnail">
<img class="img-responsive user-photo" src="https://ssl.gstatic.com/accounts/ui/avatar_2x.png">
</div><!-- /thumbnail -->
</div><!-- /col-sm-1 -->
<div class="col-sm-11">
<div class="panel panel-default companel">
<div class="panel-heading companel-heading">
<strong>'.$posts->author_name.'</strong> <span class="text-muted">'.unix_to_human($posts->post_date).'</span>
</div>
<div class="panel-body">
'.$posts->post.'
</div><!-- /panel-body -->
</div><!-- /panel panel-default -->
</div><!-- /col-sm-11 -->';
}
?>
now i want to except first result or first post in my case ? it is possible
and another question may i do something like display posts but one by one i mean align one right and second one left?
You can initialize a variable outside the foreach and count inside the iteration.
$count=0;
foreach($allposts as $posts)
{
$count++; // incrememnt
if($count==1)
{
// this is the first post
}
}
Option 2:
Use for loop instead of foreach
for($i=0; $i<=count($allposts); $i++)
{
if($i==0) // this is the first post.
echo $allposts[$i];
}
Using CSS to float your posts:
.post:nth-child(odd){
float: left;
}
.post:nth-child(even){
float: right;
}
You can declare a var $count outside the foreach loop, initilize it to 0 and increment it at the end of the loop. At the beginning of the loop check if the $count variable is 0 - if that is the case - skip the echo.
To display one row aligned to the left and one to the right check the same $count variable: if $count%2 == 0 then align one direction else the other.
foreach($value as $k => $v)
{
if($k === 0)
{
continue;
}
// rest your case
}

Repeating an HTML element with incrementing variables

I currently have a simple html list. What I want is to repeat this list item with each repeated element having a variable that will increase by one, each time it is repeated.
The php calls that i have included in the above list item is from the Advanced Custom Field plugin on WordPress. The variable I want to change is the number inside of those php calls.
<ul>
<li>
<?php the_field('vendor_1_name'); ?> <!--the number is the variable that i want to increase by one with each repition-->
<a href="http://<?php the_field('vendor_1_url'); ?>" target="_blank"/>
<?php the_field('vendor_1_url'); ?>
</a>
</li>
</ul>
I have an idea of how to do this using an array, but I would love to hear other methods on how to do something like this. Thanks!
<ul>
<?php for ($z = 0; $z < $n; $z++) : ?>
<li>
<?php the_field('vendor_'.$z.'_name'); ?>
<a href="http://<?php the_field('vendor_'.$z.'_url'); ?>" target="_blank">
<?php the_field('vendor_'.$z.'_url'); ?>
</a>
</li>
<?php endfor; ?>
</ul>
Where $n is the number of times it should iterate.
Use a for loop. If you have an array of items (are you grabbing vendors from a database?), just iterate through the array:
<?php
// fetch values and define $vendors
// using sql is highly recommended
echo "<ul>\n";
for ($i = 0; $i < count($vendors); $i++) {
echo "<li><a href='".$vendors[$i]['vendor_url']."'>".$vendors[$i]['vendor_name']."</a></li>\n";
}
echo "</ul>\n";
?>
Note that the array would say vendor_name instead of vendor_1_name because the field is not going to have the iteration in its name.

PHP echoing a specific amount of rows

I have a table in my database with 100 names, dates, id's, and other stuff. I want to be able to get a specific amount of rows echoed in a div, and then another specific amount in the next and so on.
I have been looking at foreach and break here, cause my googling kind of sent me there.. but maybe im looking at the wrong thing:
http://php.net/manual/en/control-structures.break.php
I just don't seem to get things right.
This is a school project and I know this is maybe a little bit vague, sorry about that.
Something like this:
<div id="div1"> echo row 1-7 </div>
<div id="div2"> echo row 7-19 </div>
<div id="div3"> echo row 20-44 </div>
and so on...
Could someone point me in the right direction?
You can do it directly in your query
Use at the end of your query this:
<div id="div1"> echo row 1-7 </div> use "LIMIT 0,6"
<div id="div2"> echo row 7-19 </div> use "LIMIT 7, 19"
<div id="div3"> echo row 20-44 </div> use "LIMIT 20,44"
if you have a numerically indexed array holding your rows you could do something like:
<div id="div1">
<?php for ($i = 1; $i <= 7; $i++) {
print $yourArray[Si]['some_field'];
} ?>
</div>
<div id="div2">
<?php for ($i = 8; $i <= 19; $i++) {
print $yourArray[Si]['some_field'];
} ?>
</div>
...
Something like this (not tested) might work:
$id=1;
$count=0;
$limit=20;
foreach($row as $r){
if ($count==0) echo "<div id='div$id'>";
echo $r;
if ($count++==$limit){
$count=0;
$id++;
echo "</div>\n";
};
}
if ($count!=0) echo "</div>";

php + Count loops + Wrong initial count?

I have a rather long code, so i think the best is I post it here with some additional comments as questions inside of it:
<div class="contentRow">
<h2>Title</h2>
<div id="frame">
<?php
//Get files
$sql->query("SELECT * FROM files WHERE job = 'true'");
$count = count($sql->get());
//No files to display
if ($count == "0"){
echo "<div class='box red'><p>No jobs found.</p></div>";
} else{
$sql->query("SELECT * FROM files WHERE job = 'true'");
$i=0;
foreach($sql->get() as $result){
$i++;
?>
<!-- Here I start printing the results and here the problems begin -->
<!-- My goal here: Print n .jobsContainer with exactly 4 .jobContainer inside -->
<?php if ($i % 4 == 0){ ?>
</div><!-- CLOSE jobsContainer -->
<?php } ?>
<?php if ($i % 4 == 0 OR $i == 1){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
<!-- Print the .jobContainer -->
<div class="jobContainer">
content + table + form
</div>
<!-- My goal here: Print .jobSeperator after every 2nd .jobContainer -->
<?php if ($i % 2 == 0){ ?>
<div class="jobSeperator"> </div>
<?php } ?>
<!-- CLOSE loop -->
<?php } }?>
</div><!-- jobsFrame -->
<div class="clear"></div>
</div><!-- contentRow -->
The desired output should look like this:
My problem is following:
It seems that there are only 3 elements included in the first container, but after that there are 4. Therefore also the seperators are kinda messed up and it looks like this:
It seems that the problem is not applying to the .jobSeperator, as it does always get included after every 2th container, however it gets messed up too, because of the fact that in the first .jobsContainer there are just 3 sub containers.
I dont get why in the first .jobsContainer there are just 3 sub containers, but from than on there are, as desired, 4, but probably it is obvious and I just dont see it...
p.s. If I set the code to print 5 .jobContainer inside one .jobsContainer, than there are printed 4 in the first .jobsContainer and from than on 5 in every following .jobsContainer
First of all, you should not keep your SQL logic mixed with HTML.
Anyway. The idea is that you need to output a separator after each second item. The testcase i would look at would be like this.
1 2
---
3 4
***
5 6
---
7
And the code for writing it would be:
$i = 0;
foreach( /* some array */ as $data ){
$i++;
if ( ($i - 1) % 2 === 0 ){
if ( ($i - 1) % 4 === 0 ){
echo '<br />***<br />';
} else {
echo '<br />---<br />';
}
}
echo $i, ' ';
}
This would reproduce the structure above (never tested).
As for the separation of layout and rest of application logic, you might look in to this article. It will show a quite simple way, without a need of additional 3rd party libraries.
try to change these lines:
<?php if ($i % 4 == 0 OR $i == 1){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
to
<?php if ( ($i-1) % 4 == 0 ){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
Now you open container at the begginning of 1st, 4th, 8th, 12th,... iteration, after this change you should open container before 1st, 5th, 9th, 13th,... iteration which should fix the problem. And you will get rid of ugly or. It seems this is the only bug, just try it.
I also suggest separating application logic and presentation.
I believe You're making one small mistake.
<!-- My goal here: Print n .jobsContainer with exactly 4 .jobContainer inside -->
<?php if ( ($i+1) % 4 == 0){ ?>
</div><!-- CLOSE jobsContainer -->
<?php } ?>
<?php if ( ($i+1) % 4 == 0 OR $i == 1){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
Use ($i+1) instead of $i in this bit.
If you inspect the generated HTML output, you'll see that when $i == 4, you first close the jobsContainer div before outputting the 4th jobContainer. You need to change the order of output to something like this:
EDIT: seems like you should split up the start of the first jobsContainer ($i == 1)
<div class="contentRow">
<h2>Title</h2>
<div id="frame">
<?php
$i = 0;
for($j = 0; $j < 12; $j++)
{
$i++;
?>
<?php if ($i == 1) { ?>
<div class="jobsContainer">
<?php } ?>
<div class="jobContainer">job</div>
<?php if ($i % 4 == 2) { ?>
<div class="jobSeperator"> </div>
<?php } ?>
<?php if ($i % 4 == 0) { ?>
</div>
<div class="jobsContainer">
<?php } ?>
<?php
}
?>
<?php if ($i > 0) { ?>
</div>
<?php } ?>
</div>
<div class="clear"></div>
</div>

Categories