Сразу к заданию или Tagliamo corto e andiamo al punto
На входе есть строка – относительный путь к файлу, например
./aa/.././bb/ccc/../../aa/some_path/file.txt
Нужно написать функцию, которая возвращает абсолютный путь к файлу и убирает все «лишние» каталоги.
Функция принимает 2 аргумента:
- $base_dir — «текущий каталог», каталог, относительного которого задан путь к файлу
- $relative_path — относительный путь к файлу
Например:
function getPath ($relative_path, $base_dir='/'){...}
$absolute_path = getPath('./aa/.././bb/ccc/../../aa/some_path/file.txt',
'/home/www/somesite.com/htdocs');
Var_dump($absolute_path);
Должно вернуть
string(51) "/home/www/somesite.com/htdocs/aa/some_path/file.txt"
Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /
Проверять пути и файлы на существование не нужно, функция просто трансформирует 2 исходных строки в одну.
Использовать специфичные файловые функции нельзя — надо решение на «голом» php. Функции для работы с массивами, строками, объектами можно использовать.
Моё решение
Способ 1
function getPath ($relative_path, $base_dir = '/')
{
$base_dir = rtrim($base_dir, '/');
$pos = strrpos($relative_path, '../');
if ($pos !== false) {
$relative_path = substr($relative_path, $pos + 2); // keep "/"
}
$relative_path = ltrim($relative_path, '/');
return implode('/', [$base_dir, $relative_path]);
}
Способ 2 (практически то же самое)
function getPath ($relative_path, $base_dir = '/')
{
$base_dir = rtrim($base_dir, '/');
$pop = '';
$pos = strrpos($relative_path, '../');
if ($pos !== false) {
$exp = explode('../', $relative_path);
$pop = array_pop($exp);
} else {
$pop = $relative_path;
}
$relative_path = ltrim($pop, '/');
return implode('/', [$base_dir, $relative_path]);
}
Ответ
n-ое задание — ни один из способов не работает корректно
Апелляция
Я, [18.06.19 16:21]
здравствуйте, так а почему не работает n-ое задание, всё же верно?
Я, [18.06.19 16:23]
получается так как и должно быть в условии
Я, [18.06.19 16:27]
«n-ое задание — ни один из способов не работает корректно» — ну как это? всё работает правильно как и в условии, можно, пожалуйста, объяснить, что не так? может для этого связаться с разработчиками, просто как было в задании — так и сделал и проверял и по ссылке вашей всё правильно
HR менеджер, [18.06.19 16:28]
Да, я уже уточняю. Вернусь к Вам с ответом как только получу фидбек
HR менеджер, [18.06.19 16:49]
[Переслано от Разработчик А]
если пройтись по строке ./aa/.././bb/ccc/../../aa/some_path/file.txt то верный ответ будет /aa/some_path/file.txt (ваш скрипт дает верный ответ)
1) ./ — Наше положение "/"
2) ./aa/ — мы заходим в аа, наше положение /aa
3) ./aa/../ — мы выходим на уровень вверх, наше положение /
4) ./aa/.././ — мы остаемся в той же папке, наше положение /
5) ./aa/.././bb/ — захоим в bb, наше положение /bb
6) ./aa/.././bb/ccc/ — заходим в ccc, наше положение /bb/ccc
7) ./aa/.././bb/ccc/../ — выходим на 1 уровень вверх, наше положение /bb
8) ./aa/.././bb/ccc/../../ — выходим на 1 уровень вверх, наше положение /
9) ./aa/.././bb/ccc/../../aa — заходим в аа, наше положение /aa
10) ./aa/.././bb/ccc/../../aa/some_path/ — захоим в папку some_path, наше положение /aa/some_path
11) ./aa/.././bb/ccc/../../aa/some_path/file.txt — добрались до файла. его полный путь /aa/some_path/file.txt
если пройтись по строке ./aa/.././bb/ccc/../some_path/file.txt то верный ответ будет /bb/some_path/file.txt (ваш скрипт дает /some_path/file.txt)
1) ./ — Наше положение "/"
2) ./aa/ — мы заходим в аа, наше положение /aa
3) ./aa/../ — мы выходим на уровень вверх, наше положение /
4) ./aa/.././ — мы остаемся в той же папке, наше положение /
5) ./aa/.././bb/ — захоим в bb, наше положение /bb
6) ./aa/.././bb/ccc/ — заходим в ccc, наше положение /bb/ccc
7) ./aa/.././bb/ccc/../ — выходим на 1 уровень вверх, наше положение /bb
8) ./aa/.././bb/ccc/../some_path/ — захоим в папку some_path, наше положение /bb/some_path
9) ./aa/.././bb/ccc/../some_path/file.txt — добрались до файла. его полный путь /bb/some_path/file.txt
Я, [18.06.19 16:52]
но по условию «Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /» — поэтому что левее "../" отбрасывается по условию
Я, [18.06.19 16:56]
это противоречит описанию прохода, кот вами скинуто, тем более что пример чётко это демонстрировал, что если есть "../" — то берётся правая часть
HR менеджер, [18.06.19 17:08]
Соискатель, похоже Вы не знаете как работает ../ в указании пути, отсюда и непонимание задачи
почитайте как работает указание пути к файлам и папкам и какую роль там играют точка(.) и две точки (..)
Я, [18.06.19 17:12]
по условию проход идёт справа, а не слева
Я, [18.06.19 17:12]
потому что «Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /»
Я, [18.06.19 17:14]
ок, не подошёл — так не подошёл, но задание просто некорректно сформулировано
HR менеджер, [18.06.19 17:17]
попытка подняться выше корня всегда оставляет в корне
вот пример
[dev_main@dev-instance-centos7 ~]$ cd /
[dev_main@dev-instance-centos7 /]$ pwd
/
[dev_main@dev-instance-centos7 /]$ cd ../
[dev_main@dev-instance-centos7 /]$ pwd
/
[dev_main@dev-instance-centos7 /]$
HR менеджер, [18.06.19 17:17]
Да, давайте останемся на связи, возможно в будущем сможем Вам предложить должность в компании
Я, [18.06.19 17:22]
так как мы находимся внутри какого-то пути, то понятие «Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /» подразумевает проход по этому пути справа налево, мы же хотим подняться из своего пути
Я, [18.06.19 17:22]
я всё равно остаюсь на своём
Я, [18.06.19 17:23]
потому что так семантически верно из условия
Я, [18.06.19 17:30]
/home/www/somesite.com/htdocs/aa/../some_path/file.txt
пытаемся подняться выше, но, учитывая «Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /» мы должны получить:
/some_path/file.txt
Я, [18.06.19 17:31]
а у вас в ответе получается чтобы подняться выше, мы должны идти сначала пути — это абсурд
Заключение
Думаю, мой подход понятен. Приведу пример:
Оживлённая трасса.Подход Разработчика А:
Через определённые промежутки могут быть автобусные остановки.
Если вы увидите остановку, то идите к ней.
Оживлённая трасса.И ещё, зачем тогда дан пример, кот. наглядно демонстрирует мою версию условия. В любом случае, даже если только я один на свете так вижу это задание, я не считаю себя упрямым и вредным соискателем, я всего лишь отвечаю на поставленную задачу.
Через определённые промежутки могут быть автобусные остановки.
Если вы увидите остановку, то идите в депо и пройдя все остановки, если они есть, дойдите до той остановки где вы были, но учтите, что по дороге могут встретиться ещё депо и не забывайте, что «Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /»
Так вот, добрались наконец-то. Хотелось бы увидеть комментарии, неужели только один я смотрю на эту задачу так, а она на самом деле очевидна и как говорит Разработчик А
Станислав, похоже Вы не знаете как работает ../ в указании пути, отсюда и непонимание задачиСогласитесь, что если ждали ответа Разработчика А фраза
Попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /должна была звучать, например так
При составлении относительного пути попытка подняться на каталог выше, чем корень / должна оставлять нас в корне /или
Попытка подняться на каталог выше, чем корень /, до самого файла, должна оставлять нас в корне /То есть подразумевается «сначала», «слева направо». Как можно подняться на каталог выше «слева», само слово «подняться» в пути семантически подразумевает проход справа налево. Но я открыт для негативных комментариев в мой адрес, вполне может быть я просто неправильно понял условие, но ведь на то и условие, чтобы оно было однозначно в понимании всех народов всех национальностей и мировоззрения, а также влекло единственно правильное решение.
И, в заключении, невозможно подняться откуда-то, не находясь там!
edogs
Согласны с HR «если пройтись по строке ./aa/.././bb/ccc/../some_path/file.txt то верный ответ будет /bb/some_path/file.txt „© и “Станислав, похоже Вы не знаете как работает ../ в указании пути, отсюда и непонимание задачи»©
Семантически? Вы филолог что-ли? В терминах «путей» разбор пути идет всегда слева-направо, при этом можно как подниматься, так и спускаться.Уточним — в пути "./aa/.././bb/ccc/../some_path/file.txt" нет поднятия выше корня /. Первые… лишь возвращают Вас выше аа, а вторые… возвращают Вас выше ссс. Выше корня тут никто никуда не идет.