code: public function removeDotSegments($path)
      {
          $new_path = '';
  
          while (! empty($path)) {
               // A
              $pattern_a   = '!^(\.\./|\./)!x';
              $pattern_b_1 = '!^(/\./)!x';
              $pattern_b_2 = '!^(/\.)$!x';
              $pattern_c   = '!^(/\.\./|/\.\.)!x';
              $pattern_d   = '!^(\.|\.\.)$!x';
              $pattern_e   = '!(/*[^/]*)!x';
  
              if (preg_match($pattern_a, $path)) {
                  // remove prefix from $path
                  $path = preg_replace($pattern_a, '', $path);
              } elseif (preg_match($pattern_b_1, $path, $matches) || preg_match($pattern_b_2, $path, $matches)) {
                  $path = preg_replace("!^" . $matches[1] . "!", '/', $path);
              } elseif (preg_match($pattern_c, $path, $matches)) {
                  $path = preg_replace('!^' . preg_quote($matches[1], '!') . '!x', '/', $path);
  
                  // remove the last segment and its preceding "/" (if any) from output buffer
                  $new_path = preg_replace('!/([^/]+)$!x', '', $new_path);
              } elseif (preg_match($pattern_d, $path)) {
                  $path = preg_replace($pattern_d, '', $path);
              } else {
                  if (preg_match($pattern_e, $path, $matches)) {
                      $first_path_segment = $matches[1];
  
                      $path = preg_replace('/^' . preg_quote($first_path_segment, '/') . '/', '', $path, 1);
  
                      $new_path .= $first_path_segment;
                  }
              }
          }
  
          return $new_path;
      }
docs: Path segment normalization
  https://tools.ietf.org/html/rfc3986#section-5.2.4