Be a Supporter!

Php: Changing Content-types

  • 1,564 Views
  • 10 Replies
New Topic Respond to this Topic
Pilot-Doofy
Pilot-Doofy
  • Member since: Sep. 13, 2003
  • Offline.
Forum Stats
Member
Level 37
Musician
Php: Changing Content-types Jul. 21st, 2006 @ 12:11 PM Reply

PHP Main - All your PHP Resource needs!

In this tutorial, I will demonstrate how we can retrieve the contents of different file types, change the content types in the header output and output the content as the selected mime type.

Note that these processes shown here will work in LOTS of circumstances. I've seen it done with mp3, wav, jpeg, gif, png, pdf, all sorts of files! This tutorial will show only the simplest of methods while outputting content of different types but I will explain what the use of this could be.

Let's say you have an image hosting company. You want to determine how many of your visitors are viewing jpegs, gifs, etc. Well, you can easily manage this by controlling image views with a database.

Let's say you setup a RewriteRule in .htaccess to foward files with a .jpg, .jpeg, and .gif extension to a .php file. While it seems absurd at this point, you can easily manage it later. You could setup the fowarding to send the requested file through a $_GET variable to the PHP file.

Once you have the file you wish to retrieve, you can store the path to file in a variable, or several other approaches are also possible. Of course, if you were going to be doing this, I would recommend a security enhanced method of retrieve these files to ensure that secure information isn't exploited through your innocent picture retreiving script.

Let's say you have the requested file in a URL variable named "pic". Self explanitory enough, right?

Let's look at some code:

<?php
// viewimage.php - This page will output the actual image
$path = $_SERVER['DOCUMENT_ROOT'] . '/uploads/pictures/' . $_GET['pic'];

$contentType = ( preg_match('#\.gif$#i', $path) ) ? 'gif' : 'jpeg';

$pictureContents = file_get_contents($path);
header('Content-type: image/' . $contentType);
echo $pictureContents;
?>

Now, it may seem a bit confusing, but I'm getting ready to explain it. Firstly, we store the remote path to the image on the server, which is (in this example) stored in the $path variable. Like I said previously, I wouldn't recommend doing it this simple because someone could easily exploit you're script!

Once we have the file name and path stored, we can assume that the file extension will be either .jpg, .jpeg, or .gif because I specified above those were the only file types accepted/monitored for activity in this imaginary site.

If you were accepting other file types, you would, of course have to do a more comprehensive search as to the actual type of the file, but we just speed through those checks in this example for brievity. And after all, it is just an example. ;)

Once we have determined the actual type of the image, it's time to get the contents of the file. The contents of an image file are not human readable, so don't attempt to manually edit the image contents or experiment with them, because you'll just run around in endless circles. If you're really curious, here is some of the output caused by the image attached below.

žë–»ÙxϱŸO­Ó¼<Z5UD®<- MŒÑàƒ IѼ«/}ž“¬;Ó=õ*¹üˆÙÔêdÚ??[ 3Ó. >«¸ÕZë9?®¦`ÓQ>†·D“¸úm

If you can interpret that, I'll give you $1.

Now that we have the content type of the image, the image contents, and we're ready to output it, there is one important modification that needs to take place. If we don't modify the headers of the page, it will assume default properties and attempt to output the contents as HTML and plain text. Well, we of course don't want the mumble-jumble above being displayed to our users, so we modify how the page is executed by the browser.

We can change how the output is rendered through the Content-type: modification to the page headers controlled in the header() function. You can see our actual Content-type: if you use logic to see what would be outputted to the header. In the situation of a file extension that is anything other than .gif, the following code will be sent to the header() function.

Content-type: image/jpeg

If a gif is encountered, it needs to be handled like so:

Content-type: image/gif

Now, the only step left to do is output the image. You can make a simple call to the echo (or print if you prefer) construct and have the image right in front of you!

Tada! That's all there is to using PHP to output a multitude of file types.

Php: Changing Content-types

NinoGrounds
NinoGrounds
  • Member since: Nov. 28, 2005
  • Offline.
Forum Stats
Member
Level 19
Programmer
Response to Php: Changing Content-types Jul. 21st, 2006 @ 01:23 PM Reply

shit, don't fucking use regex, no one can't understand it!!

lol. awesome.
Craige
Craige
  • Member since: Jul. 17, 2004
  • Offline.
Forum Stats
Member
Level 08
Blank Slate
Response to Php: Changing Content-types Jul. 21st, 2006 @ 01:59 PM Reply

At 7/21/06 01:23 PM, Nino_JoJ wrote: shit, don't fucking use regex, no one can't understand it!!

lol. awesome.

Yuo could if you learmed them. That is a rather simple expression, although for something so simple I would probably just use stristr().

Anyway, this was quite informative. I didn't realise echo could be used for that. I figured there would be some special fumction for it; guess not.

Pilot-Doofy
Pilot-Doofy
  • Member since: Sep. 13, 2003
  • Offline.
Forum Stats
Member
Level 37
Musician
Response to Php: Changing Content-types Jul. 21st, 2006 @ 04:20 PM Reply

At 7/21/06 01:59 PM, Craige wrote: Yuo could if you learmed them. That is a rather simple expression, although for something so simple I would probably just use stristr().

Well, I wouldn't recommend just using stristr() for this type of thing, but using a strpos() call could work and use the strlen() function to calculate where the extension should occur within the string.

I just used a regular expression for brievity. In a case like this, it really won't sacrafice performance any more.

henke37
henke37
  • Member since: Sep. 10, 2004
  • Offline.
Forum Stats
Member
Level 30
Blank Slate
Response to Php: Changing Content-types Jul. 22nd, 2006 @ 02:54 AM Reply

That script is not just allowing images to be viewed. I can read any file I know of.
Like sensitive files containing passwords.


Each time someone abuses hittest, God kills a kitten. Please, learn real collision testing.

authorblues
authorblues
  • Member since: Jun. 21, 2005
  • Offline.
Forum Stats
Member
Level 12
Blank Slate
Response to Php: Changing Content-types Jul. 22nd, 2006 @ 02:56 AM Reply

At 7/22/06 02:54 AM, henke37 wrote: That script is not just allowing images to be viewed. I can read any file I know of.
Like sensitive files containing passwords.

care to elucidate?


BBS Signature
Pilot-Doofy
Pilot-Doofy
  • Member since: Sep. 13, 2003
  • Offline.
Forum Stats
Member
Level 37
Musician
Response to Php: Changing Content-types Jul. 23rd, 2006 @ 12:26 AM Reply

At 7/22/06 02:54 AM, henke37 wrote: That script is not just allowing images to be viewed. I can read any file I know of.
Like sensitive files containing passwords.

Hence my quotes from the tutorial itself. I just skimmed through and found these two statements addressing that exact issue.

"Of course, if you were going to be doing this, I would recommend a security enhanced method of retrieve these files to ensure that secure information isn't exploited through your innocent picture retreiving script."

"Like I said previously, I wouldn't recommend doing it this simple because someone could easily exploit you're script!"

DFox
DFox
  • Member since: Aug. 9, 2003
  • Offline.
Forum Stats
Member
Level 30
Blank Slate
Response to Php: Changing Content-types Jul. 23rd, 2006 @ 12:28 AM Reply

I think people forget tutorials are for LEARNING purposes. Just because he shows an example it doesn't mean go out and use it as is and it's all good.


BBS Signature
Pilot-Doofy
Pilot-Doofy
  • Member since: Sep. 13, 2003
  • Offline.
Forum Stats
Member
Level 37
Musician
Response to Php: Changing Content-types Jul. 23rd, 2006 @ 12:28 AM Reply

At 7/22/06 02:56 AM, authorblues wrote: care to elucidate?

Well, you could specify a reverse path and cause the script to display files even from the server root. Say your server setup is like so:

/servername/mysite/public_html/

Well, your web accessible content is stored in /public_html/ and beyond, but the stuff in /mysite/ before the /public_html/ directory can't be seen, or shouldn't be seen rather.

Let's say you have a password file in the /mysite/ folder called "secureinfo.txt". You could get it like so:

resizePicture.php?pic=/../../secureinfo.tx
t

Depending on how many directories forward the picture file is, of course.

God help me for teaching kids how to "hack".
authorblues
authorblues
  • Member since: Jun. 21, 2005
  • Offline.
Forum Stats
Member
Level 12
Blank Slate
Response to Php: Changing Content-types Jul. 23rd, 2006 @ 10:26 AM Reply

At 7/23/06 12:28 AM, Pilot-Doofy wrote:
God help me for teaching kids how to "hack".

i knew all about that, but it just occurred to me that changing the mimetype will only have an effect if the bytecode that is output is actual picture bytecode. i didnt even think of what would happen if its not a picture.

of course exif_imagetype (or alternatively, getimagesize) would solve that problem, right?


BBS Signature
Pilot-Doofy
Pilot-Doofy
  • Member since: Sep. 13, 2003
  • Offline.
Forum Stats
Member
Level 37
Musician
Response to Php: Changing Content-types Jul. 23rd, 2006 @ 01:31 PM Reply

At 7/23/06 10:26 AM, authorblues wrote: of course exif_imagetype (or alternatively, getimagesize) would solve that problem, right?

Well of course, you could add some very useful and easy statements to the code to make it do these checks. If it doesn't have an extension of .jpeg, .jpg, or .gif return an error to the user.

If the mimetype doesn't correspond with the file extension, return an error for that. Of course, if one of these errors arised you would neither retrieve nor output the content of the file selected.

Why didn't I include this? Because I was more focused on my 2 page long functions tutorial. ;)