LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   php scripts cant locate filenames with spaces (https://www.linuxquestions.org/questions/programming-9/php-scripts-cant-locate-filenames-with-spaces-874805/)

latavish 04-13-2011 11:17 AM

php scripts cant locate filenames with spaces
 
Hi and good morning guys,

I have a fresh dedicated server that im currently configuring and needed a little help if I may ask.

The problem is that i'm having a file naming issue.

for example from the web I can access any file that does not have spaces of any type.
ex
/music/musicfile.mp3
this works fine and my php script can locate it

But the problem is when I try to access a file that has spaces.
ex
/music/The Eagles - Hotel California.mp3

my php script can't seem to locate any files like this with spaces but doesn't have a problem locating the files with no spaces.

I also took a look at the directory within shell. I did notice that files that have spaces are showing up in this formatt in shell.

#/home/~username/public_html/music/The\ Eagles\ -\ Hotel\ California.mp3

In shell , i'm assuming that unix/linux maybe adds a backslash before spaces. But when I FTP to this same directoy, the filename look normal and at windows standard.

how could I correctly access these types of files within my php scrits? or would I need to have all uploaded files renamed so that spaces are replaced with underscores maybe??

any help would be greatly appreciated!

Latavish

hda7 04-13-2011 12:28 PM

Your php script may not be handling spaces correctly. Without the script it will be hard to locate the problem.

Also, the reason that the shell adds backslashes before the spaces is that the shell normally breaks arguments up at whitespace, so if you say
Code:

cd My Documents
for example, the "cd" builtin gets "My" as its first argument. Either My\ Documents or "My Documents" will make the shell interpret this as one argument.

hda7 04-13-2011 12:38 PM

Are you getting the file names from the url? If so, the web browser is probably encoding the spaces as "%20". Try calling "urldecode" on the filenames.

Ramurd 04-13-2011 01:46 PM

and put the filename between double-quotes, maybe use addslashes(), but in general double-quoting helps tons...

Renaming the files to contain no spaces is actually a better idea, as some discussion has gone some decades ago about how allowing spaces in filenames was a very bad idea.

Nominal Animal 04-13-2011 02:55 PM

Quote:

Originally Posted by latavish (Post 4323491)
my php script can't seem to locate any files like this with spaces but doesn't have a problem locating the files with no spaces.

I just rechecked a very simple PHP script, which takes the file name as a GET parameter, and it works flawlessly without any tricks. Specifically, both
http://myserver/testscript.php?file=some file.txt
http://myserver/testscript.php?file=some+file.txt
work fine in Firefox and in wget. The script correctly receives the GET parameter file,
Code:

$_GET['file'] === 'some file.txt'
and
Code:

$name = preg_replace('/[^-\. 0-9A-Z_a-z]+/', '', @$_GET['file']);
$content = @file_get_contents('path to the directory/' . $name);

correctly reads the file contents. The preg_replace() is there to remove all unwanted characters from the file name; it only keeps spaces, dashes (-), dots (.), underscores (_) and ASCII letters and numbers, and removes everything else. I always do something like that, because I trust nobody, not even myself. (Then again, my PHP scripts have been found to be quite secure.)

Quote:

Originally Posted by latavish (Post 4323491)
I also took a look at the directory within shell.
I did notice that files that have spaces are showing up in this formatt in shell.

That is actually ambiguous information. If you use tab expansion, the backslashes show up because the shell needs to know they're not separators, but a part of the file name.

What does ls -l ~username/public_html/music/ actually show? I'd expect
Code:

-rw-r--r-- 1 username group bytes 2011-01-01 00:00:00 The Eagles - Hotel California.mp3
but ignore any differences in the cursive fields, since they depend on your system and the file itself.

There are many reasons you might be having a problem. Excessive quoting (using magic_quotes_gpc, magic_quotes_runtime, et al), for example. The problem may be due to php.ini misconfiguration, or a bug in your PHP code.

I'd suggest you first try this very simple PHP script:
Code:

<?PHP
$path = '/home/username/public_html/music/';
$file = preg_replace('/[^-\. 0-9A-Z_a-z]+/', '', @$_GET['file']);
$data = @file_get_contents($path . $file);
$length = strlen($data);
if ($length > 0) {
    header('Content-Type: audio/mpeg');
    header('Content-Length: ' . $length);
    echo $data;
} else
if ($data === FALSE) {
    header('Content-Type: text/plain');
    echo "Cannot read file '", $file, "'.\n";
} else {
    header('Content-Type: text/plain');
    echo "File '", $file, "' is empty.\n";
}
?>

and then try loading the MP3 using URLs
http://yourserver/path-to-the-script.php?file=The+Eagles+-+Hotel+California.mp3
http://yourserver/path-to-the-script.php?file=The Eagles - Hotel California.mp3
If it works, and gives (or at least tries to give) you the MP3 file via your browser, there is nothing wrong in your file names or php.ini settings; the problem must be in your PHP script.

If that does not work, but URLs
http://yourserver/~username/music/The Eagles - Hotel California.mp3 http://yourserver/~username/music/The+Eagles+-+Hotel+California.mp3
do open the MP3 file via your browser, then the issue is in your php.ini settings. Most likely you're mangling your GET/POST parameters via some magic quotes thingy. Don't use them, please.

If you cannot open the file directly either, your server (Apache) configuration is suspect; it may even be set up to rewrite URLs containing spaces. Remove those, and retry from the beginning.

When you create your actual scripts, note that you probably shouldn't read the entire file as-is. You'd most likely want to replace the file_get_contents() and strlen() with filesize() and readfile(). That way your script uses much less memory, for example. It is also possible to support efficient HTTP streaming even using a PHP script by advertising and parsing the byte range headers; see RFC 2616, especially section 14.35, for the HTTP/1.1 specification details regarding this. In that case you'll only output a small chunk of the desired data instead of the entire file. For example, VLC can use that for rewinding and skipping when getting media via http.

(For a very high-volume HTTP streaming site, like a network radio or something, it is better to use the initial PHP script to create a symlink in a web tree to the media file outside the web tree (but still accessible for Apache), using a random name (use mt_rand() to create the file names), optionally including the client address (REMOTE_ADDR), responding with a simple Location: to redirect the client to the actual symlink. Then, run a simple script or daemon on the server, using either find or inotifywait or both to remove the symlinks after a suitable period (a few minutes) has passed since their creation. This way you can use a lightweight HTTP server like LigHTTPD to serve the static media files, but Apache to respond to the initial queries and run your PHP scripts, but the direct media links cannot be easily shared.)

Hope this helps.


All times are GMT -5. The time now is 10:21 AM.