Is there a way in PHP how to determine an absolute path given a relative path without actually resolving symlinks? Something like the realpath
function but without symlink resolution.
Or alternatively, is there some easy way to check whether user (who uses my browsing PHP script to view files) did not accidentally step out of Apache virtual host's home directory? (or disallow him to use the nasty . and .. in paths)
Thanks!
I don't know PHP native solution for this, but here's one nice absolute path implementation from a comment in the PHP docs:
Because realpath() does not work on files that do not exist, I wrote a function that does. It replaces (consecutive) occurences of
/
and\
with whatever is inDIRECTORY_SEPARATOR
, and processes/.
and/..
fine. Paths returned byget_absolute_path()
contain no (back)slash at position 0 (beginning of the string) or position -1 (ending).function get_absolute_path($path) { $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutes = array(); foreach ($parts as $part) { if ('.' == $part) continue; if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } return implode(DIRECTORY_SEPARATOR, $absolutes); }
A test:
var_dump(get_absolute_path('this/is/../a/./test/.///is'));
Returns:
string(14) "this/a/test/is"
As you can see, it also produces Yoda-speak. :)
(edited for formatting & typos)