Подтвердить что ты не робот

Объединить каталог и имя файла в PHP (эквивалент Path.Combine в .Net)

Это должен быть простой вопрос, но я просто не могу вспомнить соответствующий API. Поиск в google с термином " скомбинировать имя каталога php" не дает никаких результатов. Поэтому я думаю, что я делаю и себя, и сообщество разработчиков, задавая этот вопрос.

Как совместить каталог и имя файла, чтобы сформировать полный путь к файлу в PHP? Скажем, имя каталога "D:\setup program", а имя файла - "mj.txt". Метод должен вернуть мне в Windows "D:\setup program\mj.txt". Конечно, метод должен возвращать правильный путь к файлу в Linux или другой ОС.

Связанная функция в .Net - это Path.Combine, но в PHP я не мог вспомнить об этом, хотя я, должно быть, видел это раньше.

4b9b3361

Ответ 1

$filepath = $path . DIRECTORY_SEPARATOR . $file;

Хотя в более новых версиях PHP неважно, в каком направлении идут косые черты, так что всегда хорошо использовать косые черты.

Вы можете получить правильный абсолютный путь, используя realpath(), это также приведет к удалению таких вещей, как лишние лишние косые черты и устранение таких ссылок, как ../, Он вернет false, если путь недействителен.

Ответ 2

Я думаю, что самый чистый и гибкий способ сделать это будет использовать функцию соединения плюс константу DIRECTORY_SEPARATOR:

$fullPath = join(DIRECTORY_SEPARATOR, array($directoryPath, $fileName));

Ответ 3

Все приведенные ответы не допускают пустых значений в $directoryPath и не обрабатывают дублирующие косые черты. Хотя это правда, что PHP очень устойчив к ошибкам, первая точка может быть фатальной, и вторая точка не должна игнорироваться, если вы пишете чистый код.

Итак, правильное решение:

function PathCombine($one, $other, $normalize = true) {

    # normalize
    if($normalize) {
        $one = str_replace('/', DIRECTORY_SEPARATOR, $one);
        $one = str_replace('\\', DIRECTORY_SEPARATOR, $one);
        $other = str_replace('/', DIRECTORY_SEPARATOR, $other);
        $other = str_replace('\\', DIRECTORY_SEPARATOR, $other);
    }

    # remove leading/trailing dir separators
    if(!empty($one) && substr($one, -1)==DIRECTORY_SEPARATOR) $one = substr($one, 0, -1);
    if(!empty($other) && substr($other, 0, 1)==DIRECTORY_SEPARATOR) $other = substr($other, 1);

    # return combined path
    if(empty($one)) {
        return $other;
    } elseif(empty($other)) {
        return $one;
    } else {
        return $one.DIRECTORY_SEPARATOR.$other;
    }

}

Единственное ограничение заключается в том, что второй параметр не должен быть абсолютным путем.

Ответ 4

Это не совсем то, что вы искали, но он должен получить массив частей пути, затем соединить части, используя DIRECTORY_SEPARATOR, затем разделить соединенные части, используя DIRECTORY_SEPARATOR, и удалить пустые части пути. Он должен вернуть оставшиеся части пути, к которым присоединился DIRECTORY_SEPARATOR.

 function path_combine($paths) {
  for ($i = 0; $i < count($paths); ++$i) {
    $paths[$i] = trim($paths[$i]);
  }

  $dirty_paths = explode(DIRECTORY_SEPARATOR, join(DIRECTORY_SEPARATOR, $paths));
  for ($i = 0; $i < count($dirty_paths); ++$i) {
    $dirty_paths[$i] = trim($dirty_paths[$i]);
  }

  $unslashed_paths = array();

  for ($i = 0; $i < count($dirty_paths); ++$i) {
    $path = $dirty_paths[$i];
    if (strlen($path) == 0) continue;
    array_push($unslashed_paths, $path);
  }

  $first_not_empty_index = 0;
  while(strlen($paths[$first_not_empty_index]) == 0) {
    ++$first_not_empty_index;
  }
  $starts_with_slash = $paths[$first_not_empty_index][0] == DIRECTORY_SEPARATOR;

  return $starts_with_slash
    ? DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $unslashed_paths)
    : join(DIRECTORY_SEPARATOR, $unslashed_paths);
}

Пример использования:

$test = path_combine([' ', '/cosecheamo', 'pizze', '///// 4formaggi', 'GORGONZOLA']);
echo $test;

Будет выводить:

/cosecheamo/pizze/4formaggi/GORGONZOLA

Ответ 5

Попробуйте эту функцию. Я использую эту функцию для удовлетворения своих собственных потребностей.

Если вы хотите проверить путь, вы должны установить для $ isReal значение true

  public static function path($base, $com = null, $isReal = false)
  {
    if(substr($base, -1)!=DIRECTORY_SEPARATOR) $base.=DIRECTORY_SEPARATOR;
    if($com) $base.=$com;
    $base = preg_replace('/(\/+|\\\\+)/', DIRECTORY_SEPARATOR, $base);
    while(preg_match('/(\/[\w\s_-]+\/\.\.)/', $base)){
      $base = preg_replace('/(\/[\w\s_-]+\/\.\.)/', "", $base);
      if(preg_match('/\/\.\.\//', $base))
        throw new \Exception("Error directory don't have parent folder!", 1);
    }
    if($isReal){
      $base = realpath($base);
      if(is_dir($base)) $base .= DIRECTORY_SEPARATOR;
    }
    return $base;
  }

Пример вывода:

var_dump(Combine::path("www///system", "Combine/../"));
// string(11) "www/system/"

var_dump(Combine::path("System", "Combine/../", true));
// string(40) "/home/snow/Desktop/localhost/www/System/"

var_dump(Combine::path("System", "Combine", true));
// string(48) "/home/snow/Desktop/localhost/www/System/Combine/"

var_dump(Combine::path("System", "Combine/notPath", true)); // if you try to create a path that does not exist
// bool(false)

var_dump(Combine::path("System", "Combine/class.Combine.php", true)); // you can also select a file
//string(65) "/home/snow/Desktop/localhost/www/System/Combine/class.Combine.php"

var_dump(Combine::path("/home/testuser\\badPath///////repair"));
// string(30) "/home/testuser/badPath/repair/"

Ответ 6

Вы можете просто конкатенировать его с константой php DIRECTORY_SEPARATOR или просто использовать косые черты. Windows, вероятно, не умрет = D