Yes it does!
realpath() returns FALSE on failure, e.g. if the file does not exist.
realpath
does path normalization and a file_exists
.
As a bonus I will give you a function I made to get similar functionality without the disk access.
/**
* This function is a proper replacement for realpath
* It will _only_ normalize the path and resolve indirections (.. and .)
* Normalization includes:
* - directory separator is always /
* - there is never a trailing directory separator
* - handles: http, https, ftp, ftps, file prefixes
* @param $path
* @return string normalized path
*/
function normalize_path($path) {
$allowed_prefixes = array("http://", "https://", "ftp://", "ftps://", "file://");
foreach ($allowed_prefixes as $prefix) {
$length = strlen($prefix);
if ($prefix === substr($path, 0, $length)) {
return $prefix . normalize_path(substr($path, $length));
}
}
$parts = preg_split(":[\\\/]:", $path); // split on known directory separators
// remove empty and 'current' paths (./)
for ($i = 0; $i < count($parts); $i += 1) {
if ($parts[$i] === ".") {
unset($parts[$i]);
$parts = array_values($parts);
$i -= 1;
}
if ($i > 0 && $parts[$i] === "") { // remove empty parts
unset($parts[$i]);
$parts = array_values($parts);
$i -= 1;
}
}
// resolve relative parts, this double loop required for the case: "abc//..//def", it should yield "def", not "/def"
for ($i = 0; $i < count($parts); $i += 1) {
if ($parts[$i] === "..") { // resolve
if ($i === 0) {
throw new Exception("Cannot resolve path, path seems invalid: `" . $path . "`");
}
unset($parts[$i - 1]);
unset($parts[$i]);
$parts = array_values($parts);
$i -= 2;
}
}
return implode("/", $parts);
}