PHP Foreach loop if field is not empty - php

I am trying to master the art of the foreach loop; I have the following code which I am using with WordPress and the Advanced Custom Fields pluging. I want to turn it into a foreach loop.
<li data-thumb="<?php the_field('image_1'); ?>">
<img src="<?php the_field('image_1'); ?>" />
</li>
<li data-thumb="<?php the_field('image_2'); ?>">
<img src="<?php the_field('image_2'); ?>" />
</li>
<li data-thumb="<?php the_field('image_3'); ?>">
<img src="<?php the_field('image_3'); ?>" />
</li>
<li data-thumb="<?php the_field('image_4'); ?>">
<img src="<?php the_field('image_4'); ?>" />
</li>
<li data-thumb="<?php the_field('image_5'); ?>">
<img src="<?php the_field('image_5'); ?>" />
</li>
I have tried writing the code below but it doesn't work, and I don't know how to limit the loop to 5 (images). Note that get_field returns the image url whilst the_field returns the image.
<?php
$i=1;
foreach (!empty (get_field('property_image.$i.')) ) {
print (' <li data-thumb="<?php the_field('property_image'.$i.'); ?>">
<img src="<?php the_field('property_image'.$i.'); ?> ">
</li> ');
$i++;
}
?>

If you know that there are only 5 items, then you would just use a for or while loop. foreach is a loop designed for looping through an array of elements, which you don't have.
Consider this loop instead:
for($i = 1; $i <= 5; $i++) {
if( !empty(get_field('property_image'.$i)) ) {
echo '<li data-thumb="' . the_field('image_' . $i) . '">';
echo '<img src="' . the_field('image_' . $i) '" />';
echo '</li>';
}
}

foreach is used to iterate over arrays, e.g.
foreach (array_expression as $value) {
// current array element
}
The syntax you're using will not work with foreach (see examples to understand how it works).

For the implementation you posted, you would be better off using a normal for loop.
for ($i = 1; $i <= 5; $i++) {
// print <li>
}
To use a foreach loop, you need to have iterate over an array. get_field("name") does not return an array, however you CAN use foreach with get_fields()
$fields = get_fields();
if( $fields )
{
foreach( $fields as $field_name => $value )
{
// Output values here
}
}
Details here: http://www.advancedcustomfields.com/resources/get_fields/

In your case for loop is better as changed in the loop value is numeric. So solution will be like:
for ($i = 1; $i<=5; $i++) {
$src = the_field('image_'.$i);
printf('<li data-thumb="%s">', $src);
printf('<img src="%s" />', $src);
print('</li>');
}
If you still want to use foreach loop then you can use built-in php function range to get required numbers.
foreach (range(1, 5) as $i) {
$src = the_field('image_'.$i);
printf('<li data-thumb="%s">', $src);
printf('<img src="%s" />', $src);
print('</li>');
}

What you probably wanted to write was a while loop up there. Foreach loops don't test a condition before a cycle. Rather, foreach loops take an array and iterate over all the values within. It can also iterate over associative arrays.
<?php
$users = array(
'user_mango' => 'John Doe',
'user_2' => 'Jacob Doe',
'user_potato' => 'Jane Doe'
);
foreach ($users as $user_id => $name) {
echo $user_id, ' - ', $name, '<br>';
}
should output
user_mango - John Doe
user_2 - Jacob Doe
user_potato - Jane Doe
I'm not a wordpress developper but if you wanted to write this code in the style you started off with, here goes:
<?php
$i = 0;
while (!empty(get_field('property_image.$i.')) && $i < 5) {
echo 'YOUR TEMPLATE CODE';
$i++;
}
while loops, unlike foreach loops, test a condition before each iteration. Here in the above example code, we have our counter variable initialized to zero. Inside the loop we increase the counter variable by one on each iteration, and in the condition, we specify that in order for the full expression to be true the counter must be smaller than 5.

Related

PHP - Closing off a div with nested loops

I have a folder with around 400 images. I'd like to put them on a page put only eight at a time. Meaning i will have all the images on the same page, but cut in sections of eight images wrapped in a box like this:
<div class="eightbox">
<img src="image1">
<img src="image2">
<img src="image3">
<img src="image4">
<img src="image5">
<img src="image6">
<img src="image7">
<img src="image8">
</div>
<div class="eightbox">
<img src="image9">
<img src="image9">
<img src="image10">
<img src="image11">
<img src="image12">
<img src="image13">
<img src="image14">
<img src="image15">
</div>
Now my code for this so far makes an output, but does not close the "eightbox" so that every new div is inside the other one.
Here's my Code:
<?php
$files = glob("images/*.*"); //loads all the images from my folder into an array
$y = ceil(count($files)/8); // The amount of images divided by eight and rounded up
$z = 1; //This counter makes the array continue outside the loop
for ($i=1; $i<$y; $i++)
{
echo '<div class=\'eightbox\'>';
for ($q=0; $q<8; $q++)
{
$num = $files[$z];
echo '<img src=\'' . $num . '\' >';
$z++;
}
echo '</div>';
}
?>
I hope this makes any sense to you and thanks in advance for helping!
EDIT: on popular demand heres a screenshot of the code i'm getting with chrome:
Screenshot of my code
An alternative which splits the files into chunks of 8 ( using array_chunk()) and then outputs each chunk at a time...
$split = array_chunk($files, 8);
foreach ( $split as $div ) {
echo '<div class=\'eightbox\'>';
foreach ($div as $file ) {
echo '<img src=\'' . $file . '\' />';
}
echo '</div>';
}
Or using implode() to output the data...
$split = array_chunk($files, 8);
foreach ( $split as $div ) {
echo '<div class=\'eightbox\'><img src=\''.
implode('\' /><img src=\'', $div).
'\' /></div>';
}
which IMHO is a little less readable, but more compact.
Using Modulo you could do this
<?php
$files = glob("images/*.*"); //loads all the images from my folder into an array
foreach ( $files as $idx=>$file) {
if ( $idx % 8 == 0 && $idx != 0){ // every 8 close a div and open a new one
echo '</div>';
echo '<div class="eightbox">';
}
if ( $idx == 0 ){ // output first div
echo '<div class="eightbox">';
}
echo "<img src='$file'>";
}
if ( $idx+1 % 8 != 0 ) { // close the last div
echo '</div>';
}
?>

How to echo a array list comma separated as a data attribute?

I run the following:
// array of images
$images = get_attached_media('image' );
// The following prints each image src and srcset
// in a img element wrapper in a container div
foreach ($images as $image) {
$ximage = wp_get_attachment_image_src($image->ID,'medium');
$img_srcset = wp_get_attachment_image_srcset( $image->ID, 'medium' );
echo '<div class="col"><img class="img-fluid" src="' .$ximage[0] . '" srcset="'.$img_srcset.'"></div>';
}
Span attribute
// With the following I am trying to loop over the array
// and output each one separated with a comma as a data attribute
<span class="imgs_span" data-time="
<?php foreach($images as $value){
echo $value . ", ";};
?>">
</span>
But I get nothing at all
$images var is an array of objects, so you should select the desired attribute to show it, for example:
<span class="imgs_span" data-time="<?php foreach($images as $k => $value){$attr = ($k == count($images) - 1) ? $value->post_date : $value->post_date . ", "; echo $attr;};?>"></span>
The full attributs list of WP_Post class with the description from the doc
If it is 1D array, you can use implode()
<span class="imgs_span" data-time="<?php echo implode(",", $images); ?>"></span>
==========================
As $images is an array of WP_Post type object then you can use array_map() just before implode():
<span class="imgs_span" data-time="<?php
echo implode(",", array_map(function($item){ return $item->post_date; }, $images);
?>"></span>

str_replace in model or the view?

Model
function Show_all_products()
{
return $this->db->get('printer')->result();
}
View
The table contents is being echoed in a loop
$i = -1;
echo '<ul class="products">'; foreach($products as $product) :
if($i % 11 == 10) echo '</ul><ul class="products">';
?>
<li><?php echo $product->name; ?> </li>
<?php
$i += 1;
endforeach;
echo "</ul>";
The product names are saved as Something_Something_Blah I cannot modify the product names as they are configured to show clean URL's and Breadcrumbs.
The issue is that the links in this view show as Something_Something_Blah
I tried to do a str_replace as $product = str_replace('_',' ', $product); However this isn't working.
How do i strip the '_' and insert \s ?
I see you have <?php echo $product->name; ?> which would mean $product is an object.
So you should call str_replace('_', ' ', $product->name);
<?php
$i = -1;
echo '<ul class="products">'; foreach($products as $product) :
$product->name = str_replace('_',' ', $product->name);
if($i % 11 == 10) echo '</ul><ul class="products">';
?>
<li><?php echo $product->name; ?> </li>
<?php
$i += 1;
endforeach;
echo "</ul>";
?>
str_replace must be called from within the foreach or an error will be returned. That was my mistake.
As per PHP documentation, str_replace() accepts a string or array as it's third argument. You are passing it an object. You should pass $product->name to it.
Furthermore, please strive to embed PHP in your HTML and not HTML in your PHP. You're going to find yourself echoing everything. You don't need to manually create the $i iterator either, because the foreach loop will create one for you, provided you use the foreach($x as $key => $val) syntax. You can lose the <?php echo $var;?> for <?= $var;?> too, AND concatenate with the . symbol:
<ul class="products">
<? foreach($products as $pK => $pV):?>
<? if($pK % 11 == 10):?></ul><ul class="products"><? endif;?>
<li>
<?= $pV->name;?>
</li>
<? endforeach;?>
</ul>

How to format a table to display images in PHP

I have images in an array and I want them to be display in a table with 3 columns!
So obviously in HTML, it is like:
<table>
<tr>
<td><img src="image1.jpg"></td>
<td><img src="image2.jpg"></td>
<td><img src="image3.jpg"></td>
</tr>
<!-- and so on... -->
</table>
So I want it to print out in PHP but the problem is the code.
My code is like this:
$photos = array( "image1",
"image2",
"image3",
"image4",
"image5",
);
foreach ($photos as $photo) {
$i = 0;
if ($i < 3) {
echo '<td><center><img src="'.$photo.'.jpg"></td>';
$i++;
} elseif ($i == 3) {
echo '</tr><tr>';
$i = 0;
}
}
I don't know what seems to be the problem and every time I echo out the variable $i, it echoes out like 11111111111111111111111111111111111111111111.
change this
foreach ($photos as $photo) {
$i = 0;
to
$i = 0;
foreach ($photos as $photo) {
Why is $i inside the foreach loop? That must be the reason. The $i gets initialized at the start of each loop cycle.
Try display:inline-block; instead in css. This works very well.
Here's an example...
<img src="image1.jpg" style="display:inline-block;>
<img src="image2.jpg" style="display:inline-block;>
<img src="image3.jpg" style="display:inline-block;>
You can even ask if you want to add text or something with the images...
I find using array_chunk for this kind of thing is more elegant.
$chunks = array_chunk($photos, 3);
foreach ($chunks as $chunk)
{
echo '<tr>';
foreach ($chunk as $photo)
{
echo '<td><img src="', $photo, '.jpg" /></td>';
}
echo '</tr>';
}
Also, don't use the 'center' tag, it is deprecated. Use CSS to align content.
Also, strictly speaking, this is not what HTML tables are for. Sure they work well. Actually, they work better than the 'proper' solution but they are not correct. Still, go ahead and use them if you just need a quick fix. It doesn't actually cause any problem to do so.

how to increment div id in php? [duplicate]

I have the following div. I would like to have mydiv1, mydiv2 and mydiv3. Is this possible to do?
Code:
<?php for($i =1; $i <3; $i++):?>
<div id="mydiv<?php $i?>" style="float:left">
<?php endfor;?>
Remove the inner for loop and you will get only 3 divs.
if you want to assign id's in div dynamically try this:
$somearray = array(
'animal'=>'cat',
'place'=>'earth',
'food'=>'orange'
);
$i=1;
foreach ($somearray as $k=>$v){
echo '<div id="div'.$i.'">'. $v .'<div>';
$i++;
}
In your code you are getting 9 elements because what you are doing is first loop through $somearray elements which is 3 times and inside that loop you again loop for 3 times using variable $i so 3*3=9. and you are getting 9 divs.
Use <?php echo $i; ?> instead of <?php $i?>.
Why do you have 9 elements? Because you're generating nine elements.
$somearray = array(
'animal'=>'cat',
'place'=>'earth',
'food'=>'orange'
);
foreach ($somearray as $k=>$v){
for($i=1;$i<=3;$i++){
echo '<div id="div'.$i.'">'. $v .'<div>';
}
}
Let me elaborate:
The above code block is equal to this set of codeblocks.
where $somearray value = 'animal'=>'cat' do this:
for($i=1;$i<=3;$i++){
echo '<div id="div'.$i.'">'. $v .'<div>';
}
and
where $somearray value = 'place'=>'earth' do this:
for($i=1;$i<=3;$i++){
echo '<div id="div'.$i.'">'. $v .'<div>';
}
and
where $somearray value = 'food'=>'orange' do this:
for($i=1;$i<=3;$i++){
echo '<div id="div'.$i.'">'. $v .'<div>';
}
All because of this:
foreach ($somearray as $k=>$v){
...
}
You don't need the inner for loop (3 x 3 = 9). You simply need a counter that you increment on each iteration of the outer loop:
<?php
$somearray = array(
'animal'=>'cat',
'place'=>'earth',
'food'=>'orange'
);
$counter = 1;
foreach ($somearray as $k=>$v){
echo '<div id="div'.$counter .'">'. $v .'<div>';
$counter++;
}
<?php
for($i =1; $i <3; $i++){
echo <<<CODE
<div id="mydiv$i" style="float:left;">
CODE;
}
?>
You need to give like,
<div id="mydiv<?php echo $i;?>" style="float:left">
it will work.

Categories