Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

PHP interpret file with spaces

Posted on 2010-09-15
11
Medium Priority
?
539 Views
Last Modified: 2013-12-25
I  have a photo gallery where the user is allowed to download a hires version of the images by clicking a link. I usually use non web safe names for the photo naming convention mainly for design purposes. This causes the PHP script to stop interpreting the file name at the first instance of  "%20". So if 50  images have the same name except for a counter, the user will be offered to download the same file name every time.

So... I need to modify the code below to properly interpret file name when it contains "%20".

download.php - this file is in the directory along with hires images.

<?php
// Force download of image file specified in URL query string and which
// is in the same directory as this script:
if(!empty($_GET['img']))
{
   $filename = basename($_GET['img']); // don't accept other directories
   $size = @getimagesize($filename);
   $fp = @fopen($filename, "rb");
   if ($size && $fp)
   {
      header("Content-type: {$size['mime']}");
      header("Content-Length: " . filesize($filename));
      header("Content-Disposition: attachment; filename=$filename");
      header('Content-Transfer-Encoding: binary');
      header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
      fpassthru($fp);
      exit;
   }
}
header("HTTP/1.0 404 Not Found");
?> 

Open in new window


This HTML code invokes the download option:
<img src="/images/download.php?img=imagename.jpg" alt="test">

Open in new window


Example: These file names work:

Game_1_Hopkins_09_10_01.jpg
Game_1_Hopkins_09_10_02.jpg

These don't:
Game%201%20Hopkins%2009%2010%2001.jpg
Game%201%20Hopkins%2009%2010%2002.jpg

I normally would use this naming convention on the original files, and my gallery design software would add the "%20" to enable the browser to interpret the file name. Which has always worked fine except in this instance, which allows a download of the original image.

Game 1 Hopkins.09.10.01.jpg

Which is:  filename:month:year:counter

Sorry for this very long winded description. Just wanted to be clear.

0
Comment
Question by:tplowe56
  • 4
  • 4
  • 3
11 Comments
 
LVL 6

Expert Comment

by:DalHorinek
ID: 33683276
try not to suppress error notifications and see, if there are any errors ...

Generally this should work.
0
 
LVL 6

Accepted Solution

by:
DalHorinek earned 500 total points
ID: 33683343
Also you should use
header("Content-Disposition: attachment; filename=".urlencode($filename));

Maybe some browsers can't handle it :)


Anyway your code works perfectly on my server no  matter what filename is used.
0
 
LVL 44

Assisted Solution

by:Chris Stanyon
Chris Stanyon earned 500 total points
ID: 33684768
You can use the urldecode function to convert the %20 back to spaces.

http://php.net/manual/en/function.urldecode.php



$filename = urldecode(basename($_GET['img'])); // don't accept other directories

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 6

Expert Comment

by:DalHorinek
ID: 33685400
This PHP does automatically.

See urldecode Warning:

The superglobals $_GET and $_REQUEST  are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results.
0
 
LVL 44

Expert Comment

by:Chris Stanyon
ID: 33685675
Apparently not!

If it does it automatically, then why are you still getting %20 in the GET variables? These are urlencoded spaces and to convert them back to spaces you need to use urldecode($string);

You could try and echo out the $_GET['img'] value (or $filename) and see what you get.







0
 

Author Comment

by:tplowe56
ID: 33685771
I have been investigating this further. The code will work fine if my gallery engine would generate the "%20" for the spaces in this instance, which it isn't and won't. So I think I need to add urlencode to the code above to get it to parse the file names which have spaces in them.

I am not a coder, I am a copy/paste coder. So I am not sure how to do it.

The code invokes a download just fine but it suggests to save every file as "game" (the first word in the file name before a space", thus allowing unsuspecting users to overwrite the last image they downloaded if they are not paying attention.
0
 

Author Comment

by:tplowe56
ID: 33685920
OK...I got it working fine now with this code:

<?php
// Force download of image file specified in URL query string and which
// is in the same directory as this script:
if(!empty($_GET['img']))
{
   $filename = basename($_GET['img']); // don't accept other directories
   $size = @getimagesize($filename);
   $fp = @fopen($filename, "rb");
   if ($size && $fp)
   {    
      header("Content-type: {$size['mime']}");
      header("Content-Length: " . filesize($filename));
      header("Content-Disposition: attachment; filename=".urlencode($filename));
      $filename = urlencode(basename($_GET['img'])); // don't accept other directories
      header('Content-Transfer-Encoding: binary');
      header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
      fpassthru($fp);
      exit;
   }
}
header("HTTP/1.0 404 Not Found");
?>


Not sure who gets the credit, I initially describe the problem wrong.
0
 
LVL 44

Expert Comment

by:Chris Stanyon
ID: 33685926
DalHorinek has already posted the code to urlencode your filename to present to your user.

Change line 13 (in your code above) to the following, and see how you get on.


 
 

 header("Content-Disposition: attachment; filename=" . urlencode($filename));

Open in new window

0
 
LVL 6

Expert Comment

by:DalHorinek
ID: 33685942
ChrisStanyon, than it probably depends on configuration, because it works for me.

See
http://www.travelcook.com/~dal/test.php?file=whatever%20with%20spaces.jpg

It's ok.

Even if you try it over telnet (to avoid browsers handling)

telnet travelcook.com 80
Trying 89.185.224.39...
Connected to travelcook.com.
Escape character is '^]'.
GET /~dal/test.php?file=whatever%20with%20spaces.jpg HTTP/1.0

HTTP/1.1 200 OK
Date: Wed, 15 Sep 2010 19:48:33 GMT
Server: Apache
X-Powered-By: PHP/5.3.1-5
Content-Length: 29
Connection: close
Content-Type: text/html; charset=UTF-8

Filename: 'whatever goes.jpg'
0
 
LVL 44

Expert Comment

by:Chris Stanyon
ID: 33686054
DalHorinek.

It worked for me aswell.

@tplowe56 said that the $filename in his script still contained the %20, which indicated that the GET array wasn't being urldecoded. Turned out to not be the case.






0
 

Author Comment

by:tplowe56
ID: 33686169
Thanks guys, experts exchange is THE place for accurate support. Mission accomplished.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
This article was originally published on Monitis Blog, you can check it here . Today it’s fairly well known that high-performing websites and applications bring in more visitors, higher SEO, and ultimately more sales. By the same token, downtime…
This video teaches users how to migrate an existing Wordpress website to a new domain.
The viewer will learn how to count occurrences of each item in an array.
Suggested Courses
Course of the Month11 days, 3 hours left to enroll

886 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question