Jump to content
Larry Ullman's Book Forums

Jpg Loop Produces N Times Last Picture


Recommended Posts

Hi Larry and others

 

I have a simple foreach loop accessing an array of up to 8 stored jpgs and I have also tested this with 3 simple repetitive entries. The objective of this script is to use one subroutine to generate new pictures at a chosen new width on the fly.

 

For each value (the master picture name) in the array I set 2 session variables and pass them to '_a_makePicByWidth.php', which is inside image tags.

// repeated test code start

$_SESSION['picName'] = $picListArray['7']['1'] . '.jpg' ;

$_SESSION['newWidth'] = 120 ;

echo '<img src="_a_makePicByWidth.php" />' ;

//repeated code end

// for testing repeated 3 times to display 3 pictures at different sizes, varying the '7' and the '120'.

 

I have tested with echos and all the parameters are available in the '_a_makePicByWidth.php' script, but the output is 3 times the same last picture at the last size specified, and the same happens with the foreach loop. There's 8 picture names in the test array, and the last one is shown 8 times. To further clarify, I can change the $newWidth parameter in the 3rd entry, then the output displays the last picture 3 times at the new size, so the iteration is occuring

 

Here's an extract from the '_a_makePicByWidth.php' script:

 

// there are other session parameters, these are just the relevant variables

$newWidth = $_SESSION['newWidth'] ;

$picName = $_SESSION['picName'] ;

 

// If I put echoes in here, I get only the last values of $picName and $newWidth whether it is the 3 test entries

// or the array/foreach loop with 8 values of filename.

 

// more or less straight out of the book

$srcPic = imagecreatefromjpeg($filePath . $picName);

list($width, $height) = getimagesize($filePath . $picName) ;

 

$newHeight = round($height * $newWidth/$width) ;

 

$newPic = ImageCreateTrueColor($newWidth, $newHeight) ;

imagecopyresampled($newPic, $srcPic, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

 

//serve the new picture

header('Content-Type: image/jpg') ;

imagejpeg($newPic);

 

// none of this below has any effect!

imagedestroy($newPic);

imagedestroy($srcPic);

$_SESSION['newWidth'] = '' ;

$_SESSION['picName'] = '';

$newWidth = '' ;

$picName = '' ;

$newPic = '' ;

exit();

// end of script

 

It's been hours and few more that I've spent on this, cannot see why the same last picture name and size are repeated. Any suggestions gratefully received.

 

ttfn

tony

Link to comment
Share on other sites

I have a feeling that something is going on with your $_SESSION superglobal. This actually sounds quite similar to an issue in JavaScript related to closure.

 

Anyway, you're probably going to have to look into the innerworkings of $_SESSION, and see exactly what's going on behind the scenes, or you could try using the GET method instead. For example, you could change the following line as follows:

 

echo '<img src="_a_makePicByWidth.php" />' ;

echo '<img src="_a_makePicByWidth.php?picName=ronald_mcdonald.jpg" />';

 

And then you could retrieve that info in the PHP script as follows:

 

$picName = $_GET['picName'];

 

Naturally, you'd have to add the info for the width as well.

 

Anyway, that's just one possible solution. To be honest, there are two things I would recommend not doing:

 

1) Not using $_SESSION for this kind of thing.

 

2) While you can call a PHP script for img src, I wouldn't recommend it. Maybe it's totally kosher, but something about it really bugs me.

 

Well, hope that helps out a little.

  • Upvote 1
Link to comment
Share on other sites

Out of interest HartleySan why does it bug you using the php as source? I haven't used php in image manipulation that much so I'm interested on your ideas. I thought it was the only way to use on the fly images inside a html page, as the headers would have already been sent??

Link to comment
Share on other sites

It's hard to answer the question beyond just "I don't like it." However, I did a little research and found the following:

 

According to the W3C specs for img tags in HTML 4.01 (and I imagine HTML5 is the same), the src attribute is used as follows:

 

src = uri [CT]

This attribute specifies the location of the image resource. Examples of widely recognized image formats include GIF, JPEG, and PNG.

(Source: http://www.w3.org/TR/1999/REC-html401-19991224/struct/objects.html#h-13.2)

 

So that right there tells me that (even if they are usable) PHP scripts should not be referenced from a src attribute. Also, I found the following on the W3C wiki:

 

src = URL potentially surrounded by spaces

Specifies a URL referencing a non-interactive, optionally animated, image that is neither paged nor scripted.

 

Again, "image" to me does not mean "PHP script". As we all know, HTML let's us get away with a lot of things that we shouldn't do. Also, looking at the XHTML specs, I don't see anything indicating anything different.

 

Furthermore, if you want to display images via a PHP script, there just seem like so many other (easier) ways.

 

For example, writing and calling a function that outputs an image to the screen, or simply doing something like the following:

 

<?php

...

<img src="' . $imagePath . '">

...

?>

 

I mean, really, is it that hard? The one exception would be images not in the web root, I suppose, but again, that is not really relevant to this discussion.

 

Well, that's just my two cents. Admittedly, I'm kinda trying to just find a reason because you asked, but something tells me it's odd, regardless.

Link to comment
Share on other sites

Hi everyone and thank you very much for your responses.

 

A couple of answers:

 

- We don't want to expose the URL of the pictures, so they are stored above the webroot. This means they can't be called from within the html using a simple path (by either us or a picture-stealer-person). Also we want to use a single master picture and resize it as required (on the fly) so if the site design changes we can make simple changes to the code to get a new size. The alternative would mean keeping or remaking many pictures and storing them accordingly.

 

- I had considered the $_GET superglobal, but initial tests had not proved successful so I had been concentrating on fixing the $_SESSION problem. However, since there doesn't seem to be a way of getting the $_SESSION to work, I have now recoded using the $_GET method for the width and name parameters. And it works! About which I am both relieved and pleased! It's crazy though as other session variables are recovered and used, so it does seem to be down to the repetitive nature of the code to display multiple pictures.

 

- I don't think there is a problem using <img src="aScript.php" /> method and I'm not aware of any other way of doing it. Given an alt attribute it certainly validates.

 

So many thanks for the stimulus of your responses. I'd prefer not to even expose the picture's name, but given the dead-end of the $_SESSION route, at least the $_GET method is up and working.

 

Thank you all.

 

//tony

Link to comment
Share on other sites

tony, at the very least, you might want to consider using a PHP script to automatically create varying sizes for each of the images, and storing them all on your server. Naturally, that means more server space being occupied, but it also means significantly faster load times (which I consider a fair trade-off).

 

As for wanting the images outside the web root, well, okay. It seems like a lot of unnecessary headaches to protect some information that seems unnecessary to protect, but then again, I'm not aware of the nature of your site.

 

Anyway, I looked into it a bit more thoroughly, and while (according to the W3C) scripts are not valid values for the src attribute, it obviously works, and is pretty much the only way to do what you want to do.

 

Well, good luck with that all. I think at this point, you have enough to go on. You still might want to try reading more about the $_SESSION superglobal. Here's a link to get you started:

 

http://www.php.net/manual/en/book.session.php

  • Upvote 1
Link to comment
Share on other sites

Hi HartleySan , thanks for your note.

 

I'm going to stick with sizing on the fly for now, and see how the server copes if this site gets busy. For now I need the flexibility until the design is stable (probably never...).

 

Thanks for that link. There's a comment at the bottom of the page from 'pushedx' which would seem to reveal the cause of the problem with $_SESSION. It suggests that the session variables are only written (= updated) at the end of the script, so my 3rd or nth entry will be the only one used, the previous values will be overwritten. So it takes the last set of values and iterates n times with those values. In this case, the $_GET array would appear to be the only way.

 

Btw, Jonathan - yes the headers already sent is a problem I've encountered when serving a jpg file via a script. That's why the external script must not even have any white space above the php tags - even a space is 'output'.

 

all the best

//tony

Link to comment
Share on other sites

I see what your saying HartleySan. I've never really thought about it to be honest, but I'm always interested in peoples thoughts. Have you got PHP5 advanced? Larry calls his images through a script, so I just assumed this was probably the better way to go. I think I'll have a look around (at some point), see what I can find on it.

 

Yes tonywuk I'm aware of this, but thanks for taking the time to reply.

Link to comment
Share on other sites

Jonathon, thanks for that info. Actually, I don't have Larry's PHP 5 Advanced book, but maybe I should get it. I have his PHP 6 & MySQL 5 book, and also a few others. Anyway, from what I had read, he had never put a script in an image tag, so I assumed he didn't approve of it either.

 

Regardless, I would be curious to hear what Larry has to say.

 

Also, tony, good find in that SESSION article. I didn't actually read the whole thing, but I figured that some pertinent info had to be in there somewhere.

 

I guess we all learned something with this topic. Thanks.

Link to comment
Share on other sites

No, I've definitely used a PHP script as the src of an image tag. I forget where and when, but I have, and would definitely recommend it as a best practice in some situations (such as serving images stored out of the Web directory or stored in a database). I also disagree with the interpretation that the W3C definition doesn't allow for using a PHP script or that it advises against so. And, arguably, even if the W3C spec DID advise against using a PHP script as a src attribute, I think of the W3C as theoretical recommendations, which don't always mesh with how things are really done or how browsers really work.

 

If HartleySan, or anyone, doesn't care for a practice, just because it rubs you the wrong way, that's completely understandable and certainly okay, and there are always 12 ways of doing things, with very few clearly better than others, but I definitely believe it's fine to use this approach when the need arises.

Link to comment
Share on other sites

Hmmm...perhaps I need to start thinking of the W3C specs more as recommendations than law. I do try to stick with them whenever in doubt.

 

Anyway, regarding proxy PHP scripts for accessing images outside of the web root, I honestly could not think of any other way to do it, so I guess it'll have to be fine. Not to mention the fact that it just plain works, which is indisputable.

 

Larry, if you don't mind me asking, if you use a proxy PHP script to load images outside of the web root, is it pretty straightforward to load a lot of images from one script, and then place HTML all around those images?

 

Thanks.

Link to comment
Share on other sites

No, you can't load multiple images using one script. Each use of the script can only send one image. To have a page display multiple images, you'd have multiple calls to the same PHP script.

Link to comment
Share on other sites

 Share

×
×
  • Create New...