PHP: escape filename as linux does

2019-06-26 23:44发布

问题:

I'm having troubles with filenames upload by users which I have to process. When I try to access them, because some of them have special characters, the command used says the file is not found or similar.

I've used escapeshellcmd with no sucess.

When I use the "tab" key in linux console (when you have started to type the filename and you want it to complete), the bash escape the filename correctly, and if I use exactly that "escaped" filename, it works.

I've tried this:

preg_replace("/[^a-zA-Z0-9\-\.\s]/", "\\\\$0", $filename)

to escape everything except numbers, letters, - and spaces ... but I found that for file "test_1.jpg", this command converts it into "test_1.jpg", and it does not work, since "_" does NOT need to be converted.

I'm afraid there could be more "allowed" characters, so my question is ... how can i "clone" the escape function of "tab" key in linux console bash ?

Thank you !

回答1:

If you want to use the file name as a shell command parameter you can use the function escapeshellarg.



回答2:

I use this for both file names and for making URLs out of blog post titles and the like.

// everything to lower and no spaces begin or end
$path = strtolower(trim($path));

// adding - for spaces and union characters
$find = array(' ', '&', '\r\n', '\n', '+',',');
$path = str_replace ($find, '-', $path);

//delete and replace rest of special chars
$find = array('/[^a-z0-9\-<>]/', '/[\-]+/', '/<[^>]*>/');
$repl = array('', '-', '');
$path = preg_replace ($find, $repl, $path);


回答3:

If you are accessing these files directly on your web server, your files names need to be url encoded with urlencode, not escapeshellcmd



回答4:

this is the function I put together, hope it helps

you can all add more by adding | with another escaped character

public function linuxFilename($file)
{
    //make the linux filename perfect
    return preg_replace("/ |'|\(|\)/", '\\\${0}', $file);
}