3

Take a look at the code

$link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
echo dirname(dirname($link));

Question 1. Is it elegant to use dirname twice to go two levels up?

Question 2. In case you want to go three levels up, would it be a good practise to use dirname three times?

Julian
  • 4,396
  • 5
  • 39
  • 51
  • 1
    If it is a fixed amount of level ups this is fine I think. But if it is always variable how many levels you want to go up. I would split the path by `DIRECTORY_SEPARATOR` and take an `array_range()` and `implode()` the new array again. Or use `str_repeat()` with `../` if it's a file path used by PHP and not exposed to the user in any way. – TiMESPLiNTER Jul 16 '14 at 10:02
  • Most simple and elegant way to get 2 folders up would be `dirname( __DIR__ )` – Tahi Reu Jan 23 '22 at 09:32

2 Answers2

1

Question 1. Is it elegant to use dirname twice to go two levels up?

I don't think it's elegant but at the same time it's probably fine for 2 levels

Question 2. In case you want to go three levels up, would it be a good practise to use dirname three times?

The more levels you have the less readable it becomes. For a large number of levels I would use a foreach and if it's used often enough then I'd put it inside a function

function multiple_dirname($path, $number_of_levels) {

    foreach(range(1, $number_of_levels) as $i) {
        $path = dirname($path);
    }

    return $path;
}
FuzzyTree
  • 32,014
  • 3
  • 54
  • 85
1

If you're looking to be more flexible in how many levels up you would like to go, then I would suggest writing a small function to help take care of this for you.

Here's an example piece of code which might do what you would like. Instead of using dirname multiple times or calling a for loop, it uses preg_split, array_slice, and implode, assuming that / is your directory separator.

$string = 'http://example.com/some_folder/another_folder/yet_another/folder/file
.txt';

for ($i = 0; $i < 5; $i++) {
  print "$i levels up: " . get_dir_path($string, $i) . "\n";
}

function get_dir_path($path_to_file, $levels_up=0) {
  // Remove the http(s) protocol header
  $path_to_file = preg_replace('/https?:\/\//', '', $path_to_file);

  // Remove the file basename since we only care about path info.
  $directory_path = dirname($path_to_file);

  $directories = preg_split('/\//', $directory_path);
  $levels_to_include = sizeof($directories) - $levels_up;
  $directories_to_return = array_slice($directories, 0, $levels_to_include);
  return implode($directories_to_return, '/');
}

The result is:

0 levels up: example.com/some_folder/another_folder/yet_another/folder
1 levels up: example.com/some_folder/another_folder/yet_another
2 levels up: example.com/some_folder/another_folder
3 levels up: example.com/some_folder
4 levels up: example.com
Alvin S. Lee
  • 4,984
  • 30
  • 34