У кого-нибудь есть более умный аналог функции:
// _path
// возвращает полный путь к файлу или директории, даже если таковая не существует
if (!function_exists("_path")):
function _path($_path) {
$path = strval($_path);
// errors
if (preg_match("#[*?\"<>|+]#", $path)) return false; // [*?"<>|+]
if (preg_match("#[.]{3,}#", $path)) return false; // ...
if (preg_match("#[^/][.]{2,}#", $path)) return false; // a..
if (preg_match("#[.]{2,}[^/]#", $path)) return false; // ..a
if (preg_match("#(.{2,}|[^.]+)\.$#", $path)) return false; //ab.[end] or ..[end]
$path = preg_replace("#[\\\/]#", "/", trim($path));
$path = preg_replace("#/+#", "/", $path);
$path = preg_replace("#^([^/.])#", ($_SERVER["DOCUMENT_ROOT"] . "/$1"), $path);
$path = preg_replace("#^/#", realpath("/"), $path);
$path = preg_replace("#^\.{2}[/]?#", (dirname($_SERVER["DOCUMENT_ROOT"]) . "/"), $path);
$path = preg_replace("#^\./#", ($_SERVER["DOCUMENT_ROOT"] . "/"), $path);
while (($pos = mb_strpos($path, "../")) !== FALSE):
$var = realpath($tmp = mb_substr($path, 0, $pos) . "../");
$left = mb_substr($path, $pos + 3) ?: null;
if ($var):
$path = rtrim($var, DIRECTORY_SEPARATOR) . "/" . $left;
continue;
endif;
break;
endwhile;
$path = preg_replace("#^\.$#", $_SERVER["DOCUMENT_ROOT"] . "/", $path);
$path = $path ?: ($_SERVER["DOCUMENT_ROOT"] . "/");
$path = preg_replace("#[\\\/]#", "/", $path);
return $path;
}
endif;
Тесты:
array(
"" => "D:/OpenServer/domains/test.wrap/test.loc/",
".." => "D:/OpenServer/domains/test.wrap/",
"/.." => false,
"/../" => "D:/",
"a.." => false,
"a/.." => false,
"a/../" => "D:/OpenServer/domains/test.wrap/test.loc/a/../",
"..a" => false,
"/..a" => false,
"/../a" => "D:/a",
"a..a" => false,
"a/..a" => false,
"a/../a" => "D:/OpenServer/domains/test.wrap/test.loc/a/../a",
"...." => false,
"../.." => false,
"../../" => "D:/OpenServer/domains/",
"..a.." => false,
"..a/.." => false,
"..a/../" => false,
"....a" => false,
"../..a" => false,
"../../a" => "D:/OpenServer/domains/a",
"..a..a" => false,
"..a/..a" => false,
"..a/../a" => false,
"/...." => false,
"/../.." => false,
"/../../" => "D:/",
"/..a.." => false,
"/..a/.." => false,
"/..a/../" => false,
"/....a" => false,
"/../..a" => false,
"/../../a" => "D:/a",
"/..a..a" => false,
"/..a/..a" => false,
"/..a/../a" => false,
"/..//.." => false,
"/..//../" => "D:/",
"/../a.." => false,
"/../a/.." => false,
"/../a/../" => "D:/a/../",
"/..//..a" => false,
"/..//../a" => "D:/a",
"/../a..a" => false,
"/../a/..a" => false,
"/../a/../a" => "D:/a/../a",
"a...." => false,
"a../.." => false,
"a../../" => false,
"a..a.." => false,
"a..a/.." => false,
"a..a/../" => false,
"a....a" => false,
"a../..a" => false,
"a../../a" => false,
"a..a..a" => false,
"a..a/..a" => false,
"a..a/../a" => false,
"a/...." => false,
"a/../.." => false,
"a/../../" => "D:/OpenServer/domains/test.wrap/test.loc/a/../../",
"a/..a.." => false,
"a/..a/.." => false,
"a/..a/../" => false,
"a/....a" => false,
"a/../..a" => false,
"a/../../a" => "D:/OpenServer/domains/test.wrap/test.loc/a/../../a",
"a/..a..a" => false,
"a/..a/..a" => false,
"a/..a/../a" => false,
"a/..//.." => false,
"a/..//../" => "D:/OpenServer/domains/test.wrap/test.loc/a/../../",
"a/../a.." => false,
"a/../a/.." => false,
"a/../a/../" => "D:/OpenServer/domains/test.wrap/test.loc/a/../a/../",
"a/..//..a" => false,
"a/..//../a" => "D:/OpenServer/domains/test.wrap/test.loc/a/../../a",
"a/../a..a" => false,
"a/../a/..a" => false,
"a/../a/../a" => "D:/OpenServer/domains/test.wrap/test.loc/a/../a/../a",
"..aa.." => false,
"..aa/.." => false,
"..aa/../" => false,
"..aa..a" => false,
"..aa/..a" => false,
"..aa/../a" => false,
"/..aa.." => false,
"/..aa/.." => false,
"/..aa/../" => false,
"/..aa..a" => false,
"/..aa/..a" => false,
"/..aa/../a" => false,
"/../aa.." => false,
"/../aa/.." => false,
"/../aa/../" => "D:/aa/../",
"/../aa..a" => false,
"/../aa/..a" => false,
"/../aa/../a" => "D:/aa/../a",
"a..aa.." => false,
"a..aa/.." => false,
"a..aa/../" => false,
"a..aa..a" => false,
"a..aa/..a" => false,
"a..aa/../a" => false,
"a/..aa.." => false,
"a/..aa/.." => false,
"a/..aa/../" => false,
"a/..aa..a" => false,
"a/..aa/..a" => false,
"a/..aa/../a" => false,
"a/../aa.." => false,
"a/../aa/.." => false,
"a/../aa/../" => "D:/OpenServer/domains/test.wrap/test.loc/a/../aa/../",
"a/../aa..a" => false,
"a/../aa/..a" => false,
"a/../aa/../a" => "D:/OpenServer/domains/test.wrap/test.loc/a/../aa/../a"
)
Или она сгодится?