/** * @brief Fix common problems with a file path * @param string $path * @param bool $stripTrailingSlash * @return string */ public static function normalizePath($path, $stripTrailingSlash = false, $addTrailingSlash = true) { if ($path == null || $path == '' || !is_string($path)) { return '/'; } //no windows style slashes $path = str_replace('\\', '/', $path); //add leading slash if (!self::isWindows() && $path[0] !== '/') { $path = '/' . $path; } // remove '/./' // ugly, but str_replace() can't replace them all in one go // as the replacement itself is part of the search string // which will only be found during the next iteration while (strpos($path, '/./') !== false) { $path = str_replace('/./', '/', $path); } //remove '/../' while (strpos($path, '/../') !== false) { $path = str_replace('/../', '/', $path); } //remove '..' while (strpos($path, '..') !== false) { $path = str_replace('..', '/', $path); } // remove sequences of slashes $path = preg_replace('#/{2,}#', '/', $path); if ($addTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) !== '/') { $path = $path . '/'; } //remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } // remove trailing '/.' if (substr($path, -2) == '/.') { $path = substr($path, 0, -2); } while (preg_match('/\\/\\//', $path)) { $path = str_replace('//', '/', $path); } //normalize unicode if possible $path = XApp_Utils_Strings::normalizeUnicode($path); return $path; }