I’m learning PHP & I’m working on a simple upload and display image exercise out of a Apress PHP book. I’m using the latest Eclipse program, XAMPP, Apache, etc…
The problem I’m having is that the image being uploaded is a JPEG but it is being read as type PJPEG. It pushes my IF
statement to the FALSE
section with my error messages.
If I change the all the criteria to pjpeg
, then for some reason I get weird raw code instead of a picture.
How do I ensure that my image being loaded stays a jpeg or how can I rewrite my code to upload and output a pjpeg
and actually display in browser.
UPDATE: the code provided by Jake is working but the image itself is not displaying in browsers. Tested in Chrome, Firefox and IE.
<?php
error_reporting(E_ALL);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ( isset($_FILES['photo']) &&
is_uploaded_file($_FILES['photo']['tmp_name']) &&
$_FILES['photo']['error']==UPLOAD_ERR_OK ){
if ($_FILES['photo']['type'] == 'image/jpeg'){
$j = imagecreatefromjpeg($_FILES['photo']['tmp_name']);
header('Content-Type: image/jpeg');
imagejpeg($j);
imagedestroy($j);
} else {
echo "Uploaded file was not a jpeg. <br />";
echo "The file ", $_FILES['photo']['name'], " uploaded was a ", $_FILES['photo']['type'];
}
} else {
echo "No photo upload";
}
} else {
?>
<form action="test.php" method="post" enctype="multipart/form-data">
<label for="photo">User Photo:</label>
<input type="file" name="photo" />
<input type="submit" name="submit" value = "Upload a JPEG" />
</form>
<?php } ?>
change
if ($_FILES['photo']['type'] == 'image/jpeg'){
to
if (preg_match('@^image/[a-z\-]jpeg@',$_FILES['photo']['type']) === true) {
this will match any type starting with 'image/' and ending with 'jpeg' and containing only lowercase letter and - characters
Change the code from this:
if ($_FILES['photo']['type'] == 'image/jpeg'){
$j = imagecreatefromjpeg($_FILES['photo']['tmp_name']);
header('Content-Type: image/jpeg');
imagejpeg($j);
imagedestroy($j);
}
To this:
// Set an array of mime types that you accept as valid.
$valid_photo_mime_types = array('image/jpeg', 'image/pjpeg');
// Now check if the mime type of the uploaded file matches your array values of valid photo mime types.
if (in_array($_FILES['photo']['type'], $valid_photo_mime_types)){
// Now let’s ingest the file that was uploaded & assign it to $j using the GD graphics library.
$j = imagecreatefromjpeg($_FILES['photo']['tmp_name']);
// Set the header to be whatever the uploaded file mime-type is.
header('Content-Type: ' . $_FILES['photo']['type']);
// Now send the image to the browser.
imagejpeg($j);
// And finally 'destroy' the stored image to free up memory.
imagedestroy($j);
}
Note that I git rid of the double-spacing of lines in your original example for space. And in my rewrite I am setting an array named $photo_mime_types
and then using in_array
to check if $_FILES['photo']['type']
matches a value in $photo_mime_types
. Then for header('Content-Type: '…
I am setting that to whatever the value of $_FILES['photo']['type']
since at that point that value is valid, correct? Well programming is about avoiding repetition so let’s just pass what is valid when we know it is valid.
EDIT: This still seems to not be working for the original poster, so another debugging idea is to check the headers sent via curl -I
from the command line. Unsure if you can do this on Windows, but if not you should figure out how to since curl
is a great debugging tool for things like this. On a Mac OS X machine or a Unix/Linux box just run this command. For example, a call to the image logo on Google right now:
curl -I https://www.google.com/images/srpr/logo11w.png
The output I get is as follows:
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 14022
Last-Modified: Wed, 09 Oct 2013 01:35:39 GMT
Date: Thu, 15 May 2014 01:47:25 GMT
Expires: Thu, 15 May 2014 01:47:25 GMT
Cache-Control: private, max-age=31536000
X-Content-Type-Options: nosniff
Server: sffe
X-XSS-Protection: 1; mode=block
Alternate-Protocol: 443:quic
Those are all of the headers that are sent with that image that tells the browser what to do with the image. Note the Content-Type: image/png
. Now just substitute the URL to your local PHP code instead of the Google URL & check the output. Also look at this answer on Stack Overflow. As well as this one that explains how to use getimagesize
to get data about the image within your PHP code. getimagesize
is useful as well to show you what PHP is seeing the data to be.