src/DataHandling.php
public static function formatPath($pathOrPaths, ...$additionalPaths)
    {
        $path = rawurldecode(self::mergePaths($pathOrPaths, ...$additionalPaths));
        $path = self::removeSchemeFromUri($path, $scheme);

        // Remove self-referencing path parts (resolving already takes care of this)
        $replacements = 0;
        do {
            $path = str_replace(["/./", "//"], "/", $path, $replacements);
        } while ($replacements > 0);

        // Replace parent directory paths if possible
        $pathParts = explode("/", $path);

        $ignoredParts = 0;
        do {
            $parentKey = array_search("..", array_slice($pathParts, $ignoredParts, null, true));

            // Don't remove .. if it starts the path
            if ($parentKey > 0) {
                switch ($pathParts[$parentKey - 1]) {
                    // Don't remove root / but remove ..'s directly after it
                    case "":
                        unset($pathParts[$parentKey]);
                        break;

                    // Keep consecutive ..'s (only possible if the path starts with them)
                    case "..":
                        $ignoredParts++;
                        break;

                    // Collapse
                    default:
                        unset($pathParts[$parentKey - 1]);
                        unset($pathParts[$parentKey]);
                        break;
                }

                $pathParts = array_values($pathParts);
            } else {
                $ignoredParts++;
            }
        } while ($parentKey !== false);

        $path = implode("/", $pathParts);

        return $scheme . $path;
    }
public static function formatPath($pathOrPaths, ...$additionalPaths)
    {
        $path = rawurldecode(self::mergePaths($pathOrPaths, ...$additionalPaths));
        $path = self::removeSchemeFromUri($path, $scheme);

        // Remove self-referencing path parts (resolving already takes care of this)
        $replacements = 0;
        do {
            $path = str_replace(["/./", "//"], "/", $path, $replacements);
        } while ($replacements > 0);

        // Replace parent directory paths if possible
        $pathParts = explode("/", $path);

        $ignoredParts = 0;
        do {
            $parentKey = array_search("..", array_slice($pathParts, $ignoredParts, null, true));

            // Don't remove .. if it starts the path
            if ($parentKey > 0) {
                switch ($pathParts[$parentKey - 1]) {
                    // Don't remove root / but remove ..'s directly after it
                    case "":
                        unset($pathParts[$parentKey]);
                        break;

                    // Keep consecutive ..'s (only possible if the path starts with them)
                    case "..":
                        $ignoredParts++;
                        break;

                    // Collapse
                    default:
                        unset($pathParts[$parentKey - 1]);
                        unset($pathParts[$parentKey]);
                        break;
                }

                $pathParts = array_values($pathParts);
            } else {
                $ignoredParts++;
            }
        } while ($parentKey !== false);

        $path = implode("/", $pathParts);

        return $scheme . $path;
    }
public static function formatPath ( $ pathOrPaths , ... $ additionalPaths ) { $ path = rawurldecode ( self :: mergePaths ( $ pathOrPaths , ... $ additionalPaths ) ) ; $ path = self :: removeSchemeFromUri ( $ path , $ scheme ) ; // Remove self-referencing path parts (resolving already takes care of this) $ replacements = 0 ; do { $ path = str_replace ( [ "/./" , "//" ] , "/" , $ path , $ replacements ) ; } while ( $ replacements > 0 ) ; // Replace parent directory paths if possible $ pathParts = explode ( "/" , $ path ) ; $ ignoredParts = 0 ; do { $ parentKey = array_search ( ".." , array_slice ( $ pathParts , $ ignoredParts , null , true ) ) ; // Don't remove .. if it starts the path if ( $ parentKey > 0 ) { switch ( $ pathParts [ $ parentKey - 1 ] ) { // Don't remove root / but remove ..'s directly after it case "" : unset ( $ pathParts [ $ parentKey ] ) ; break ; // Keep consecutive ..'s (only possible if the path starts with them) case ".." : $ ignoredParts ++ ; break ; // Collapse default : unset ( $ pathParts [ $ parentKey - 1 ] ) ; unset ( $ pathParts [ $ parentKey ] ) ; break ; } $ pathParts = array_values ( $ pathParts ) ; } else { $ ignoredParts ++ ; } } while ( $ parentKey !== false ) ; $ path = implode ( "/" , $ pathParts ) ; return $ scheme . $ path ; }
Formats a file path to a uniform representation.
Multiple paths can be given and will be concatenated.

@param string|string[] $pathOrPaths
@param string[] $additionalPaths
@return string
Formats a file path to a uniform representation . Multiple paths can be given and will be concatenated .