tags:

views:

319

answers:

5

Hi everyone,

I'm storing banner ads in a mysql table or I should say just the file name e.g: 'imagename.jpg' or 'banner3.gif'.

Obviously I am wanting to track when these banners are loaded so I'm thinking to create a php file called img.php and call it like so

<img src="/img/img.php?imageID=3" />

And that would pull out the image with the id 3 along with updating my hits table etc.

I know how to update my hits table... but what I'm trying to work out is how to code the img.php file so that it simply retrieves the file name and prints it to screen so it works like a regular image.

So far I've got...

<?php
header("Content-Type: image/jpeg");
// insert my db connect file
// update the hits table etc

$sql = 'SELECT * FROM ads WHERE id="' . $_GET['imageID'] . '" ';
$res = mysql_query($sql);

$row = mysql_fetch_array($res);

$image = '/img/' . $row['file'];

imagejpeg($image);

// and this is where I'm at...

?>

I have some problems with the above code which i've extracted from various places to get here. The images could be png/gif/jpg while the header content-type seems to only have space for one type.

Is there a way to have this one file work ok for multiple image types? I'm thinking I should query the table firstly, work out the file extension and then insert the header function based off that.

But what do I actually do when I've got that right and I want the image to then just appear?

thanks to your help here is the final working file

<?php

// make sure we're only getting a number for the query b4 doing stuff
if(is_numeric($_GET['imid'])) {

include('thedbfile.php');

$types['jpg'] = 'image/jpeg';
$types['png'] = 'image/png';
$types['gif'] = 'image/gif';



$sql = 'SELECT file FROM ads WHERE id="' . $_GET['imid'] . '" ';
$res = mysql_query($sql);

$row = mysql_fetch_array($res);

$image = 'img/banners/' . $row['file'];

$extension = end(explode('.', $row['file']));


header('Content-Type: ' . $types[$extension]);

echo file_get_contents($image);


}

?>
+2  A: 
echo file_get_contents($image);

But I doubt your images are actually in /img/ (top level of filesystem hierarchy). And yes, setting up Content-type after you know what type your image is sounds good.

P.S. you extended your code a bit and I have no idea what imagejpeg($image) does ;-)

Michael Krelin - hacker
thanks for that... you were right about the img folder thing! cheers
cosmicbdog
+1  A: 

you can try a header('Location: <URL-TO-IMAGE>'); after you are done with the image.

alternatively, you can detect the extension from file name, and then return the appropriate MIME type.

function mime2ext($mime){
    $m = explode('/',$mime);
    $mime = $m[count($m)-1];
    switch($mime){
        case 'jpg': return 'jpg'; break;
        case 'jpeg': return 'jpg'; break;
        case 'pjpeg': return 'jpg'; break;
        case 'png': return 'png'; break;
        case 'gif': return 'gif'; break;
    }
    return '';
}

function ext2mime($fname){
    $ext = end(explode('.',$fname));
    switch($ext){
        case 'jpg': return 'image/jpeg'; break;
        case 'jpeg': return 'image/jpeg'; break;
        case 'png': return 'image/png'; break;
        case 'gif': return 'image/gif'; break;
    }
    return '';
}

regarding multiple mime type, there's no multiple mime type. Only the latest Content-Type will be sent.

see:

<?php
header('Content-Type: image/jpeg');
header('Content-Type: image/png');
header('Content-Type: image/gif');
?>

The content-type is image/gif.

thephpdeveloper
Why would you need a `break` statement after a `return`?
Samir Talwar
just my usual practice. case: break;
thephpdeveloper
+2  A: 

Something like this will ensure you deliver the image correctly and ensure it is not cached so that a page reload will trigger a new fetch...

//tell client abou tcontent type
header("Content-Type:image/jpeg");

//prevent caching
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");    // Date in the past
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header ("Cache-Control: no-cache, must-revalidate");  // HTTP/1.1
header ("Pragma: no-cache");                          // HTTP/1.0

//how big is it?
header("Content-Length:".filesize($image));

//send image data
readfile($image);
Paul Dixon
this is awesome. extra cool additions!!
cosmicbdog
what is better readfile() or file_get_contents() ? *heads to php.net*
cosmicbdog
For your purposes, readfile is better as will perform a buffered read/write to the output butter. file_get_contents will read the entire file into a string first, then you must echo it out.
Paul Dixon
+2  A: 

You may want to store the image content directly in your Database.

As you said, you need to parse the content type out of the filename. You could also add a field to your database which contains the extension.

$extension = end(explode('.', $row['file']));

Then you have to create an array which contains the header content-type:

$types['jpg'] = 'image/jpeg';
$types['png'] = 'image/png';

then send the header (you will want to check whether the types array contains the extension key and error if it doesn't)

header('Content-Type: ' . $types[$extension]);

Then load your image with

echo file_get_contents($image);

That should do it. Note that you really have to check whether the ImageID parameter is an integer, for safety reasons:

if(!ctype_digit($_GET['ImageID'])) // error
JoostK
+1  A: 

In the end, you just need to turn the image data in the body of your message, along with the right hearder. My code looks like:

header("Content-type: $mime");
echo $this->mBinaryJunk;

You need to set $mime type correctly based on the actual type of the image. You can do this by storing it when you original find the file, or detecting it from the file name.

ndp