breaking output of php array into chunks - php

I have an array containing information about some images, which I am using to print a number of img html tags by a foreach loop as follows:
<?php foreach ( $images as $image ) : ?>
<img alt="<?php echo $image->alttext ?>" src="<?php echo $image->thumbnailURL ?>" />
<?php endforeach; ?>
I would like to wrap a div around every 10 images. The remainder should get a div as well.
I am thinking I need to use array_chunkon $images and wrap the above in another loop for each chunk. The little bit of math I did to start is as follows:
$pics_per_page = 10;
$imgcount = count($images);
$num_pages = ceil($imgcount/$pics_per_page);
$pages = array_chunk($images, $num_pages);
How do I proceed from here? How do I use the $images array correctly, if at all, in outputting my HTML?
Forgetting about the array_chunk method, I have the following way, but the array_chunk method seems cleaner.
for i from 1 to num_pages:
echo "<div>"
j = (i-1) * pics_per_page;
while j <= i * pics_per_page
echo "<img src = "$images[j]->thumbnailURL />";
endwhile;
echo "</div>"
Thanks for your help in advance,
Sepehr

You are using array_chunk [docs] wrongly. You just have to specify the size of each chunk:
$chunks = array_chunk($images, 10);
Then you need a nested for (foreach) loop:
<?php foreach($chunks as $chunk): ?>
<div class="someClass">
<?php foreach($chunk as $image): ?>
<img alt="<?php echo $image->alttext ?>" src="<?php echo $image->thumbnailURL ?>" />
<?php endforeach; ?>
</div>
<?php endforeach; ?>

You could use it without array_chunk too.
<?php
$imgTot = count($images);
echo '<div>';
for($i=0; $i<$imgTot; $i++)
{
if ($i % 10 == 0) {
echo '<div>';
}
echo '<img alt="'.$image->alttext.'" src="'.$image->thumbnailURL.'" />';
if ($i % 10 == 9) {
echo '</div>';
}
}
echo '</div>';
?>
See the working example here: http://codepad.org/FkdTEH91

Related

Skipping For Loop

After having a solution to this question.
my code:-
<?php for ($i = 1; $i <= 9; $i++):?>
<div class="col-md-2">
<div class="thumbnail">
<a href="<?php echo $details . $i;?>.php">
<img src="<?php echo $images . $i;?>.png" alt="<?php echo $i;?>">
</a>
</div>
</div>
<?php endfor; ?>
So now assume that there is now image as 8.png, so for loop should skip that and go to next, without showing no image.
Result is.
And I want this
The red Portion should not be displayed.
Since you stated in the comments that the URL to the images is localhost/downloads/vf/images, I will assume that with usage of $_SERVER['DOCUMENT_ROOT'] takes care of the folders outside public (which could be something like C:\users\chirag\htdocs\, but that $_SERVER variable should take care of that. If that's not the case, find the full path and use that instead - as file_exists() requires the system path, not the public path/URL. This also assumes that you use a relative path for the $images variable, which means that you have $images = "/downloads/vf/images/"; and not $images = "localhost/downloads/vf/images/";.
With that assumption, we can now use file_exists() - because that takes the system path, not the URL.
<?php
$images = "/downloads/vf/images/";
for ($i = 1; $i <= 9; $i++):
if (!file_exists($_SERVER['DOCUMENT_ROOT'].$images.$i.".png"))
continue; // Skip this iteration if it can't find the file
?>
<div class="col-md-2">
<div class="thumbnail">
<a href="<?php echo $details . $i;?>.php">
<img src="<?php echo $images . $i;?>.png" alt="<?php echo $i;?>">
</a>
</div>
</div>
<?php endfor; ?>
PHP.net on continue;
PHP.net on $_SERVER
PHP.net on file_exists()
You will have to add a check condition if the image exists or not, there are certain methods like file_exists
<?php for ($i = 1; $i <= 9; $i++):
if(file_exists("file_path")){ ?>
<img src="<?php echo $images . $i;?>.png" alt="<?php echo $i;?>">
<? { php endfor; ?>
This might help you: How to check if image exists
Use this code
File_exists is function check for the file exists or not
<?php for ($i = 1; $i <= 9; $i++):
if (file_exists($images.$i.'.png')) { ?>
<img src="<?php echo $images . $i;?>.png" alt="<?php echo $i;?>">
<?php } endfor; ?>
check this like for more detail
PHP: How to check if image file exists?
You need to use the continue directive. I also suggest you drop the use of : and endfor and all the extra PHP start/end blocks for readability and performance reasons.
<?php
for ($i = 1; $i <= 9; $i++) {
if (!is_readable($images . $i . '.png'))
continue;
echo "<img src=\"${images}${i}.png\" alt=\"$i\">";
}
?>
If you use the keyword continue inside any loop, the rest of the iteration after that would be skipped.
<?php for ($i = 1; $i <= 9; $i++): ?>
<?php if ($i == 8) continue;>
<img src="<?php echo $images . $i;?>.png" alt="<?php echo $i;?>">
<?php endfor; ?>
This keyword is common for a lot of languages.
Also in PHP, the continue accepts a numeric argument which tells it how many iterations it should skip.
PHP continue

Php foreach loop, add to different div depending on if/else

My current code:
<?php if($_images){?>
<?php $i=0; foreach($_images as $_image){ $i++; ?>
<?php if($i > 2) { ?>
<div class = "largePic">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(600,900); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
</div>
<?php } else { ?>
<div class = "smallPic">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(450,675); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
</div>
<?php } ?>
<?php } ?>
<?php } ?>
So this is obviously wrong since every time an image is echo'ed it's assigned to a different div (same name but different). Is it possible to assign echoes to certain div depending on the count?
For example, first two images will be assigned to the smallPic div, then the rest will be in the largePic div.
Process the images first (storing the HTML for each image in either an array or string) and then create the div elements- see example below. This will reduce the number of opening/closing tags immensely.
Also note that if the keys of the array are numeric then the following syntax can be used instead of creating an extra variable (i.e. $i) just to track the index (so as to avoid extra bookkeeping like incrementing the variable - one of the major benefits of foreach compared to a for statement).
foreach (array_expression as $key => $value)
statement 1
<?php
$largePic = '';
$smallPic = '';
if($_images){
foreach($_images as $i => $_image){
if($i > 2) {
$largePic .= '<img src="'.$this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(600,900).'" alt="'. $this->htmlEscape($_image->getLabel()). '" title="'. $this->htmlEscape($_image->getLabel()).'" />';
} else {
$smallPic .= '<img src="'. $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(450,675). '" alt="'. $this->htmlEscape($_image->getLabel()). '" title="'. $this->htmlEscape($_image->getLabel()). '" />';
}
}
} ?>
<div class = "largePic"><?php echo $largePic; ?></div>
<div class = "smallPic"><?php echo $smallPic; ?></div>
What you want is to first devide your array into two arrays and then foreach through both of them.
<?php
$largeImages = array();
$smallImages = array();
foreach ($_images as $k => $v) {
if ($k > 2) {
$largeImages[] = $v;
} else {
$smallImages[] = $v
}
}
?>
<div class = "largePic">
<?php foreach ($largeImages as $_image) { ?>
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(600,900); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
<?php } ?>
</div>
<div class = "smallPic">
<?php foreach ($smallImages as $_image) { ?>
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $_image->getFile())->resize(450,675); ?>" alt="<?php echo $this->htmlEscape($_image->getLabel());?>" title="<?php $this->htmlEscape($_image->getLabel());?>" />
<?php } ?>
</div>
I'm not in PHP but I'm quite sure for start you can loose those extensive open/close tags (<?php ?>) and replace it with only one at the start and the end. This is hardly readable.
Then, like in many server side scripts, what you need is some kind of buffer containing HTML which you will output at the end of loop. Because what you're doing now is outputting from inside the loop, this sending multiple DIVs to client.
Create largePic nad smallPic variables contianing DIVs HTML, and append HTML to it inside loop (instead outputing it to client like you do now). Then, after loop is finished, output those two variables to client.

Use PHP to increment number for image ID

So, I have a problem in that I have 67 (and counting) images all named IMAGE01.jpg, IMAGE02.jpg all the way to IMAGE67.jpg.
In my HTML page, I have this code to display the image.
<article class="thumb">
<img src="images/thumbs/image01.jpg" alt="" />
</article>
So, I have this for 67 images. Is there a way of incrementing the image number using PHP? So I can just copy and paste that piece of code for the number of images I have?
That's the first part that would be GREAT to have a solution too. But, would there be a way to not have to repeat that code for every image? Would it be possible to use PHP to define the number of times I want this to be repeated?
So have the snippet of code once and have something to repeat it a defined number of times so as I add to the collection, all I have to do is change the repeat times?
Many thanks in advance for the help. Means allot.
<?php
for($i=1; $i<=67; $i++) {
?>
<article class="thumb">
<a href="images/fulls/image<?php
if($i<9)
echo "0".$i;
else
echo $i;
?>.jpg" class="image"><img src="images/thumbs/image<?php
if($i<9)
echo "0".$i;
else
echo $i;
?>.jpg" alt="" /></a>
</article>
<?php
}
?>
To make what you want you need to use a for loop from 1 to 67 (because your image name are from 1 to 67). And for each iteration you have to echo the html string.
Like this for example :
for($i = 1; $i<=67; $i++){
$name = $i<10?"0".$i:$i;
echo "<article class='thumb'>
<a href='images/fulls/image".$name.".jpg' class='image'>
<img src='images/thumbs/image".$name.".jpg' alt=''/>
</a>
</article>";
}
You need to construct the name if the name need to have 0 before (01, 02 ...). It's what I make here :$name = $i<10?"0".$i:$i;. It's mean that if $i < 10 then we add a "0" before else the name is $i.
You can also use a while loop :
$i = 1;
while($i<=67){
$name = $i<10?"0".$i:$i;
echo "<article class='thumb'>
<a href='images/fulls/image".$name.".jpg' class='image'>
<img src='images/thumbs/image".$name.".jpg' alt=''/>
</a>
</article>";
$i++;
}
It's the same idea.
Hope that helps you.
You can use a PHP variable and inject it into your HTML. The following code will count from 1 - 67.
<?php
$count = 1;
while($count <= 67){
?>
<p>Count: <?php echo $count; ?></p>
<?php
$count +=1;
}
?>
So you could use it as such:
<article class="thumb">
<?php
$count = 1;
while($count <= $numOfImages){
?>
<img src="images/thumbs/image<?php echo $count; ?>.jpg" alt="" />
<?php
$count +=1;
}
?>
</article>
Just set $numOfImages to however many images there are and it should work.
You can try this sample code below if images are one after the other. Using single for loop with printf inside echo...
<body>
<?php
for ($i = 0; $i < 67; $i++) {
?>
<article class="thumb">
<a href="images/full/image<?php printf("%02d\n", $i)?>.jpg" ><img src="images/thumb/image<?php printf("%02d\n", $i)?>.png" alt="" /></a>
</article>
<?php
}
?>
</body>
Here is the sample output I kept only one image for testing. http://i.stack.imgur.com/l1Lo5.png

Two items per foreach loop

Apologies if this has already been asked (I cannot find an answer) but I am using PHP and I am building a slider, but would like two images per slide, not one. So, in theory the foreach() needs to include two per each.
An example of the setup is as follows:
<?php foreach ($page->images as $image) : ?>
<img src="<?php echo $image->url; ?>"/>
<?php endforeach; ?>
I was thinking I could do something like a count...
<?php $index = 0; foreach ($page->images as $image) : ?>
<img src="<?php echo $image->url; ?>"/>
<?php $index++; ?>
<?php if ( $index % 2 == 0 && $index !=count($page->images) ) : ?>
<li></li>
<?php endif; ?>
<?php endforeach; ?>
But I got a little confused as this would insert something every 2... not include two of whatever the foreach loop is fetching at once.
Hope this makes sense and thanks in advance
Why so complicated? Use a simple for loop instead:
<?php for ($i=0; $i<count($page->images)-1; $i+=2) { ?>
<img src="<?php echo $page->images[$i]->url; ?>"/>
<img src="<?php echo $page->images[$i+1]->url; ?>"/>
<?php } ?>
Or even more elegant, a do/while loop:
<?php $i=0; do { ?>
<img src="<?php echo $page->images[$i++]->url; ?>"/>
<img src="<?php echo $page->images[$i++]->url; ?>"/>
<?php } while ($i<count($page->images)) ?>
Compared to using a foreach loop these approaches have another advantage: you do not create copies of all objects. This can make a huge difference if those objects are non-trivial.
Okay, I managed to work this out... hopefully it will help.
<div class="each-slide">
<?php $index = 0; foreach ($page->images as $image) : ?>
<img src="<?php echo $image->url; ?>"/>
<?php $index++; ?>
<?php if ( $index % 2 == 0 && $index !=count($page->images) ) : ?>
</div><div class="each-slide">
<?php endif; ?>
<?php endforeach; ?>
</div>

show only three records and then move to next line

This is a very basic problem but I am very new to PHP.
I need to show results in such scenario that only three records in same line then add <br /> and then on next line, same thing should happend. I am unable to make its logic and in a great trouble :(
Right now, I am just using the simple way i.e.
while($data = mysql_fetch_array($res_set)) {
?>
<div><?php echo $data['name']?><img src="images/<?php echo $data['image']?>" /></div>
<?php
}
this is my code
$cnt = 0;
while ($prd = mysql_fetch_array($res)) {
?>
<div class="imageRow">
<?php
$cat_id = $prd['cat_id'];
$sql = "select * from tbl_category where id = $cat_id";
$cat_res = mysql_query($sql);
$cat_data = mysql_fetch_array($cat_res);
$cat_name = $cat_data['name'];
?>
<div class="set">
<div class="single first">
<img src="<?php echo $ru ?>admin/product_images/<?php echo $cat_name ?>/large/<?php echo $prd['thumb_img'] ?>" style="height: 100px; width: 100px;" /><br />
Choose
</div>
</div>
</div>
<?php
$cnt = $cnt++;
if($cnt%3 == 0) {echo "<br />";}
}
//echo $cnt;
?>
any help will be appreciated.
Thanks
<div class="imageRow">
<?php
$i = 0;
while($data = mysql_fetch_array($res_set)) { ?>
<div>
<?php echo $data['name']; ?><img src="images/<?php echo $data['image']; ?>" />
</div>
<?php
$i++;
if($i % 3 == 0) {
echo '</div><div class="imageRow"><br />';
}
}
?>
</div>
Explanation:
Set the variable $i to a number, which will then be used to keep track of how many items you've written.
Then, within the while loop, increment $i ($i++), which is the same as $i = $i + 1; By doing this, you always know which item you're on - whatever the value of $i is. Some people choose to set it to 1 initially then increment at the very end - other like to set it to 0, and set it near the beginning - either is completely fine - whatever you need it to do / whichever way you like better.
Lastly, check if $i is evenly divisible by 3 (kind of like remainder - it's called "mod" and is represented by the percent symbol). If it is, then echo a line break.
Try this
<?php
echo "<div>";
while($data = mysql_fetch_attay($res_set)) {
?>
<div style="width:30%; float:left"><?php echo $data['name]?><img src="images/<?php echo $data['image']?>" /></div>
<?php
}
echo "</div>";
?>
Output
<div>
<div>1</div> <div>2</div> <div>3</div>
<div>1</div> <div>2</div> <div>3</div>
<div>1</div> <div>2</div> <div>3</div>
</div>
That's some super ugly code you have there. This will do what you need, and is cleaner.
<?php
$i=1;
while($data = mysql_fetch_attay($res_set)) {
$frame = '<div><img src="%s" /></div>';
printf($frame, $data['image']);
if($i % 3 == 0) { echo '<br />'; }
$i++;
}
Also, <img> elements are already block elements to begin with, you really don't need to wrap another <div> around them.

Categories