| 10:19 am on Jan 13, 2012 (gmt 0)|
This seems to be an area of browser incompatibilities. You could try rawurlencode()'ing the $filename to encode the spaces as %20 (% encoded, character triplet).
| 3:30 pm on Jan 13, 2012 (gmt 0)|
Thanks I'll give that a try.
| 3:55 pm on Jan 13, 2012 (gmt 0)|
Ok I narrowed down the problem using Firefox.
The browser is attempting to download "Rock" instead of "Rock With You.mp3". It stops at the space. Anyone have any suggestions? It seems like it's a simple fix that I am missing.
| 4:22 pm on Jan 13, 2012 (gmt 0)|
I assume the %20 (space) did not work?
You could also try enclosing the filename in double quotes. Whilst I have read in comments that you should not use double quotes, I have been unable to find a definite answer to this in the specification. In the browsers I've tested in the past it has worked OK with or without double quotes.
Incidentally, the space in the filename works OK for me in Safari Windows. When you say "any Apple product", were you referring to Safari on Mac OSX?
| 4:35 pm on Jan 13, 2012 (gmt 0)|
Yea unverified that you tried
Reason being, there's no longer pluses once it is in PHP's $_GET/$_POST/$_REQUEST and when you output the file name to the browser you may have to re-encode it.
<not sure on this one> Also be sure the format is supported on the device? I know Androids won't allow normal formats to download for video/audio, but the iPhone/iPad should. Just something to check.
| 6:30 pm on Jan 13, 2012 (gmt 0)|
Ok I tried Opera 11.52, FF 9, IE 9, Chrome 16, Safari 5.1.2, and all work except for FF 9. In FF 9, the file it tries to download is just "Rock". It stops at the first space.
On the iPhone 4G, it shows a crossed out play button which tells me it translated the file type, but not the file. So I bet it's the same issue. I'm stumped.
This is the link format and the download.php code respectively:
| 6:51 pm on Jan 13, 2012 (gmt 0)|
Sorry I did not answer the questions. I did try double quotes, and I tried the %20 instead of +, and I get the same issue under both circumstances.
In order for it to work across the board I have preg_replace changing any non-standard chars into "_". That works for all, but it's a crappy workaround imo. The files like Can't Let You.mp3 turn into Can_t_Let_You.mp3 and work fine. It's just not correct to do it that way.
| 7:43 pm on Jan 13, 2012 (gmt 0)|
|...and I tried the %20 instead of + |
Just to clarify, as this is a little misleading, the %20 should be in the Content-Disposition (capital 'D') header (it doesn't matter whether the original URL contains + or %20), as rocknbil explains.
header("Content-Disposition: attachment; filename=".rawurlencode($file));
If all this still doesn't work then it's looking like a problem with the iPhone?! I might be able to fire up FF9 later to give it a go.
Another option is to omit the ;filename=$file portion altogether. You'll get prompted with some filename decided by the browser - possibly related to the name of your script - but it should at least download.
| 12:21 am on Jan 14, 2012 (gmt 0)|
I found the workaround. I had to place the $filename variable within double quotes and escape them. The files now work on all browsers and the iphone! The URL encoding wasn't a factor. The issue was not being able read the variable as a string. Single quotes won't work, and I think it's because it makes the variable literal if I am not mistaken.
Thank you guys very much for your help!
| 10:49 am on Jan 14, 2012 (gmt 0)|
Glad you got it sorted.
|The issue was not being able read the variable as a string. Single quotes won't work, and I think it's because it makes the variable literal if I am not mistaken. |
The resulting HTTP response header is:
Content-Disposition:attachment; filename="Rock With You.mp3"
The double quotes are simply a mechanism, defined in the HTTP protocol (not PHP), for grouping together a bunch of tokens. The space would ordinarily seem to be a delimiter. (Having since found this in the spec [ietf.org] - see below). So the fact that the iPhone fails when it gets to the space seems to be that it is just following the HTTP spec more closely(!) - other browsers would seem to bend the rules a bit in this respect!?
Following on from my post above [webmasterworld.com] - including double quotes is actually mentioned in the spec after all (after having had a closer read). RFC 6266 [ietf.org] (that describes the Content-Disposition header) states that the value can be a quoted-string, and RFC 2616 [ietf.org] defines a quoted-string, "...A string of text is parsed as a single word if it is quoted using double-quote marks....".
I can only conclude that the comments/articles I have previously read (and bookmarked!) regarding not using double quotes are outdated, written at a time when browser support was poor (the Content-Disposition header was not actually part of the spec in the early days) - I just wish more people would date their work! :)
| 5:27 pm on Jan 14, 2012 (gmt 0)|
Thank you for the follow up! It was very useful and informative.
I have a system setup for a cover band where they can log into their site, upload a song to learn, and it in turn emails everyone in the band the links to download the file. While this seems straight forward I have come across several issues trying to maintain the original text formatting. The first was the header for the download prompt in this post, the second was preparing the information for storage, and the third is how email clients interpret the link from the download.php.
The easy way is to use preg_replace to remove unwanted characters, and replace spaces with underscores. Seems like cheating to me :)
| 10:49 pm on Jan 15, 2012 (gmt 0)|
|...and the third is how email clients interpret the link from the download.php. |
Just a thought... instead of passing the filename directly in the link, you could pass an id that your script looks up to get the real filename. (This would also be a lot more secure.)
| 1:38 pm on Jan 16, 2012 (gmt 0)|
Thank you that's a great idea.