Объединить каталог и имя файла в PHP (эквивалент Path.Combine в .Net)
Это должен быть простой вопрос, но я просто не могу вспомнить соответствующий API. Поиск в google с термином " скомбинировать имя каталога php" не дает никаких результатов. Поэтому я думаю, что я делаю и себя, и сообщество разработчиков, задавая этот вопрос.
Как совместить каталог и имя файла, чтобы сформировать полный путь к файлу в PHP? Скажем, имя каталога "D:\setup program
", а имя файла - "mj.txt
". Метод должен вернуть мне в Windows "D:\setup program\mj.txt
". Конечно, метод должен возвращать правильный путь к файлу в Linux или другой ОС.
Связанная функция в .Net - это Path.Combine, но в PHP я не мог вспомнить об этом, хотя я, должно быть, видел это раньше.
Ответы
Ответ 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