> ...$paths A set of paths to merge, each one either a string or an array * of path fragments. * * @return string The merged path, the path intersecting fragments removed. */ public static function merge( ...$paths ) { $merged_paths = ''; if ( count( $paths ) > 2 ) { $slice = array_splice( $paths, 0, 1 ); $paths = array_merge( $slice, [ static::merge( ...$paths ) ] ); } $path_1 = isset( $paths[0] ) ? $paths[0] : ''; $lead_slash = is_string( $path_1 ) && $path_1 !== ltrim( $path_1, '\\/' ) ? DIRECTORY_SEPARATOR : ''; $path_2 = isset( $paths[1] ) ? $paths[1] : ''; $trail_slash = is_string( $path_2 ) && $path_2 !== rtrim( $path_2, '\\/' ) ? DIRECTORY_SEPARATOR : ''; // Handle *nix spacing escape sequence (`\ `) correctly. The Windows one (`^ `) is already handled. $break_pattern = '/[\\\\\\/](?!\\s)/'; $drop_empty_strings = static function ( $frag ) { return $frag !== ''; }; $path_1_frags = is_array( $path_1 ) ? $path_1 : array_filter( (array) preg_split( $break_pattern, $path_1 ), $drop_empty_strings ); $path_2_frags = is_array( $path_2 ) ? $path_2 : array_filter( (array) preg_split( $break_pattern, $path_2 ), $drop_empty_strings ); $non_consecutive_common = array_intersect( $path_1_frags, $path_2_frags ); $trimmed_path_2 = trim( preg_replace( '#^' . preg_quote( implode( DIRECTORY_SEPARATOR, $non_consecutive_common ), '#' ) . '#', '', implode( DIRECTORY_SEPARATOR, $path_2_frags ) ), '\\/' ); $merged_paths .= $lead_slash . implode( DIRECTORY_SEPARATOR, $path_1_frags ); if ( $trimmed_path_2 ) { $merged_paths .= DIRECTORY_SEPARATOR . $trimmed_path_2 . $trail_slash; } return $merged_paths; } }