Displaying My Pics Query

Hi,

i am trying to build a websit to display my photoes. At present, my photoes are displayed vertically with text underneath describing the picture, 1 picture underneath another. Now, what i want to do is somehow display them in a 2-column style.

The problem is how do i incorporate this into my php foreach for-loop? Should i use divs with CSS?



<body>
		<p>
			 
			
			<?php if( isset($images) ): ?>
			<table>
			<?php foreach ($images as $image): ?>
			
			<tr valign="top">
				<td><?php echo '<img src="./images/'.$image['Filename'].'" width="300" height="300" >';  ?> </td> 
			</tr>
			
			<td> <?php echo "<b>Description:</b> ".$image['Description'] . " <br>"; ?> </td>
			</tr>
			
			<?php endforeach; ?>
			</table>
			<?php endif ;?>
		</p>
	</body>




Your opinion would be greatly appreciated.

  1. It’s inappropriate to wrap a table inside a paragraph, because then it’s quite obviously NOT a table.

  2. Opening and closing <?php ?> on every line makes for a confusing mess of code. There’s a reason I usually won’t open/close PHP more than once per FILE. (on top of clarity, it’s also good security since no require/include should output anything if called directly) – your second snippet is a ‘mein gott’ as … well, I lack the words in polite company.

  3. valign, much like align, border and bgcolor has NO *** BUSINESS in your markup. That’s CSS’ job!

  4. </tr></td> – ok, apparently you don’t understand how tag nesting works and/or tables. TD’s inherently have to be INSIDE TR, so closing them in that order is BACKWARDS.

  5. that doesn’t appear to be tabular data, since you’ve only got one TD per TR, meaning you will only get a single column out of that. If there’s only one column, table is the wrong tags to use.

  6. There is no reason to EVER state ./ in a url.

  7. using double quotes when you don’t have to not only takes longer to run and is more code, it’s just sloppy once you start having to escape values.

  8. There is no reason to switch away from foreach - that wasn’t even close to your problem.

  9. I’m still trying to figure out just what it is you are even trying to do, as so far you’re just making a single column.

This:


<?php
	echo '
<body>';

	if (isset($images)) {
	
		echo '
			<div class="images">';
	
		foreach ($images as $image) {
					
			echo '
				<div>
					<img
						src="images/',$image['Filename'],'"
						width="300" height="300"
						alt="',htmlspecialchars($image['Description']),'"
					/><br />
					<b>Description:</b>',$image['Description'],'<br>
				</div>';
		}
		
		echo '
			<!-- .images --></div>';
	
	}
	
	echo '		
</body></html>';
?>


Is PROBABLY all you should have in your markup – EVERYTHING else you are trying to do belongs in the CSS.

Though that hinges on just exactly how tall your description field is, which to have them ‘stack’ properly (since I’d use floats or display:inline-block) they all have to be the same height.

It comes down to the question: Do you want the number of images to change with the screen width, or do you want them to be dynamic height – the two are mutually exclusive. If you want to use tables, you have to figure out how many you want per line (and cache the description line in a variable to output it as a separate TR from the images line!). If you want a variable number per line, you can’t use a table.

That’s incorrect. The secondary loops (the ones using $j) initialize themselves to 0 whenever they’re started because of their beginning statements: for($j = 0; $j<$step; $j++).

When run, the loop looks like this, assuming a step of 2:


//First $i loop
$i = 0, $j = 0: image[0]
$j++, image[1]
$j=0, description[0]
$j++, description[1]

//Second $i loop
$i + 2, $j = 0: image[2]
$j++, image[3]
$j=0, description[2]
$j++, description[3]

//Third $i loop
$i = 4, $j = 0: image[4]
$j++, image[5]
$j=0, description[4]
$j++, description[5]

The cause of this is the first parameter in the for() loop. Every time a new run of one of the $j based loops is run, we reinitialize $j to 0, which happens for the image row, then the description row, then $i increments and it all happens again - but with an $i offset of $i+$step. You should be able to increase step to 3, 4 or however many columns you want, and the loops will adjust themselves accordingly because of the way I’ve set them up.

Someone’s grumpy.

Yes, the markup is mess, no it’s not tabular data, but the poster came in here asking how to complete this task in a 2-column style (see the first post, read it thoroughly)

Rather than coming in here and berating the poster, why not calmly and without the salty talk explain what should be done and why.

Oh, and if you’d paid any attention to my posts, you’d see why the move from foreach was needed when attempting to preserve the original structure while also allowing for multiple columns. Let’s allow this poster to grasp the intricacies of iterating through data in more than one way, so that in the future they will have more options for their code in their arsenal.

Remember, all code sucks. Things we did 5 years ago seem as unforgivable now as what we do now will be absurd 5 years from now. Calm down, give some polite, constructive criticism, and move on.

I had THOUGHT that was what I did. Jesus H jumped up Mary and Joseph are people REALLY this thin ******* skinned?!? see, THAT’s Salty :wink:

Huh, I’d just wrap them and float them, and fix their height… Though if you want clearing behavior that’s easy enough without wasting the iterating variable if that’s a result from a query. To be brutally frank if I came across the amount of redundant logic flow and counter handling present in that last post of yours, I’d slap the developer who did it with a wet trout – since two column does NOT need to be that needlessly complex.

It’s called the array key… which as a result from a query is simply the row number, so you don’t need a separate counter.


<?php
	if (isset($images)) {
	
		echo '
			<div class="images">';
	
		foreach ($images as $key => $data) {
					
			echo '
				<div class="',(
					$key&#37;2==0 ? 'odd' : 'even'
				),'">
					<img
						src="images/',$data['Filename'],'"
						width="300" height="300"
						alt="',htmlspecialchars($data['Description']),'"
					/><br />
					<b>Description:</b>',$data['Description'],'<br>
				</div>';
		}
		
		echo '
			<!-- .images --></div>';
	
	}
?>


For two rows that’s all that’s needed. “.odd” gets a clear, both get floated, and if there’s the IE perfect width float drop bug rearing it’s ugly head, put a negative right margin on “.even”

God forbid anyone point out the negative or wasteful - oh it must be an attack!!! Where I’m from that WAS polite constructive criticism… SERIOUSLY, where was that impolite? Frank perhaps - laden with sardonic wit most certainly…

How laughably pathetic.

Alright, error messages aside, you have an HTML problem.


<?php echo "</tr></td>"; ?>
            <?php endfor; ?>

You’re closing your row before you close your td. That is backwards.

The undefined offset is caused by this:


            <?php for ($i=0; $i <= count($images); $i++): ?>

If you have 4 items in an array, count() will return 4, but since arrays start at index 0, your highest index will be 3. Your loop is instructing PHP to go up to and including 4.

To solve this, simply remove the ‘=’ from your condition, like so:


            <?php for ($i=0; $i < count($images); $i++): ?>

This will be true as long as $i is less than your image count, but not when it is equal to it. In an array with 4 items, this would use the indexed 0, 1, 2, and 3, then fail the test at 4 and exit the loop.

I hope this helps!

Hi,Zarin Denatrose,
thanks for your post, that does actaully help, BUT, before i saw your post, i wanted to find if i could find another way, purley for learning purposes as there is always more than 1 way to skin a cat. I did some reserach online, and came to this tutorial link: http://www.tizag.com/phpT/forloop.php

and discovered that it kinda does what i want. So i read the tutorial and tried a few things and so far i’ve got this:



<?php if( isset($images) ): ?>
			
			<?php echo "<table border=\\"1\\" align=\\"center\\">"; ?>	    
			<?php for ($i=0; $i <= count($images); $i++): ?>
			
			    <?php echo "<tr><td>"; ?> 
				<?php echo '<img src="./images/'.$images[$i]['Filename'].'" width="300" height="300" >';  ?>
			    <?php echo "<br />"; ?> 
	   		    
			 <?php echo "<b>Description:</b> ".$images[$i]['Description']; ?> 
			 
			 <?php echo "</tr></td>"; ?>
			<?php endfor; ?>
			
			<php echo "</table>"; ?>
			<?php endif ;?>

 

So far, it does not do what i hoped it for to do, right now it simply displays all my images verticaly in the center of my page with the text underneath, however, next to each image seems to be a large white space, like another <td> so to speak which makes room for another image(hope that makes some sense).

Also, i get the following error messages: “: Undefined offset: 4 in C:\wamp\www\Shanghai2010\homepage.html.php on line 20”

"Undefined offset: 4 in C:\wamp\www\Shanghai2010\homepage.html.php on line 23
Description: "

which both points to the …$images[$i][‘Description’]… and $images[$i][‘Filename’]… line.

Would somebody mind assisting me with this please.
Thnks

Thanks for the assist, Zarin Denatrose, i’m sorry for being a bother but i wanted to ask you about u’r code because i think i’m misreading incorrectly.

When PHP makes is making it’s first pass, both the j variables are equal to 0 so obviously[0 + 0] which would output the first picture along with it’s description. Then they get incremented at the end of the loop to a value of 1 along with i = 2.

But, what i don’t get is, when php makes it’s next pass and outputing the next picture, [i + j] = [1+2] = 3. Am i right in saying that it would output the picture that is in index 3? If this is the case, it should output picture 4 because i would imagine:

index:   pic
0          p1
1          p2
3          p4
...         ...

Obviously, my logic wrong, do you mind clarifying this for me please. Apologise if this seems a bother.

I always try to stay away from tables if I can, but I suppose in this instance they could be helpful.

Because of the way you need to fetch your data, a foreach loop isn’t all that helpful. If you use a for loop, you can move about your array using its indexes, and get data based on your current position in the array.

I’ve written some code here that should let you scale this to any number of columns without causing an issue.


<body>
        <p>
            
           
            <?php if( isset($images) ): ?>
            <table>

            <?php 
			$step = 2;
			for ($i = 0; $i < count($images); $i+=$step): ?>
            <tr valign="top">
				<?php for($j = 0; $j < $step; $j++): 
					if(isset($images[$i+$j])):
				?>
                <td><?php echo '<img src="./images/'.$images[$i+$j]['Filename'].'" width="300" height="300" >';  ?> </td>
				<?php 
					endif;
				endfor; ?>
            </tr>
            <tr>
				
				<?php for($j = 0; $j < $step; $j++): 
					if(isset($images[$i+$j])):
				?>
	            <td> <?php echo "<b>Description:</b> ".$images[$i+$j]['Description'] . " <br>"; ?> </td>
				
				<?php 
					endif;
				endfor; ?>
            </tr>
           
            <?php endfor; ?>
            </table>
            <?php endif ;?>
        </p>
    </body>

I hope this helps.