karelwintersky / arris.entity.path
Arris µFramework: Path builder
Package info
github.com/ArrisFramework/Arris.Entity.Path
pkg:composer/karelwintersky/arris.entity.path
Requires
- php: ^8.2
Requires (Dev)
- phpunit/phpunit: ^8
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Утилитарный класс для построения и манипуляции файловыми путями.
NB: Документация сделана нейросетью, хотя код написан руками.
Установка
composer require karelwintersky/arris.entity.path
use Arris\Entity\Path;
Быстрый старт
// Создать путь из строки $path = new Path('/var/www/html'); echo $path; // /var/www/html // Создать через фабричный метод $path = Path::create('uploads/images'); echo $path->toString(); // uploads/images // Соединить с подпутём. // join() по умолчанию = каталог завершающий '/'; для файла — trailingSeparator: false // не используйте такой способ, правильно - ниже $full = Path::create('/var/www')->join('html/index.php', trailingSeparator: false); echo $full; // /var/www/html/index.php // Правильный способ для файлов $full = Path::create('/var/www')->join('html')->joinName('index.php'); echo $full; // /var/www/html/index.php
Создание экземпляра
Конструктор
new Path(string|array|Path $path, ?bool $isAbsolutePath = null, ?bool $hasTrailingSeparator = null)
Принимает путь в одном из трёх форматов:
// Строка $p = new Path('/foo/bar/baz'); // Массив сегментов $p = new Path(['foo', 'bar', 'baz']); // Другой экземпляр Path $copy = new Path($existingPath);
Автоопределение флагов из строки:
| Входная строка | isAbsolutePath |
hasTrailingSeparator |
|---|---|---|
/foo/bar |
true |
false |
foo/bar/ |
false |
true |
/foo/bar/ |
true |
true |
foo/bar |
false/null |
false |
| `` (пустая) | true |
false (путь → /) |
/ |
true |
false |
Схлопываются:
- множественные слэши:
foo//bar///baz→foo/bar/baz - точки
.→ `` ../fooилиfoo/..→.→ ``
Фабричные методы create() / from()
Path::create(string|array|Path $path, ?bool $isAbsolutePath = null, ?bool $hasTrailingSeparator = null): Path Path::from(string|array|Path $path, ?bool $isAbsolutePath = null, ?bool $hasTrailingSeparator = null): Path
Эквивалентны конструктору (и друг другу), но удобнее для цепочек вызовов:
$path = Path::create('/var/www') ->setTrailingSeparator(true); $copy = Path::from($existingPath); // то же, что new Path($existingPath)
Иммутабельность: переданный инстанс
Pathстрингифицируется без мутации исходника (черезtoString()с его текущим трейлинг-сепаратором). Это касается конструктора,create(),from()иjoin().
Методы
Получение строки
toString(?bool $hasTrailingSeparator = null): string
Экспортирует путь в строку. По умолчанию (null) уважает внутренний флаг hasTrailingSeparator:
путь-каталог выведется с завершающим разделителем. Явные true/false принудительно
добавляют/снимают разделитель в выводе (флаг инстанса не меняется):
$p = new Path('foo/bar/'); $p->toString(); // foo/bar/ $p->toString(false); // foo/bar $p->toString(true); // foo/bar/
__toString(): string
Псевдоним toString() без аргументов. Позволяет использовать объект в строковом контексте:
echo new Path('/etc/nginx'); // /etc/nginx
Соединение путей
join(mixed $data, ?bool $trailingSeparator = null): Path
Возвращает новый экземпляр с добавленным сегментом. По умолчанию трактуется как
присоединение каталога: результат получает hasTrailingSeparator = true. Явный
$trailingSeparator переопределяет это поведение — например, для склейки пути к файлу.
$base = new Path('/var/www'); $dir = $base->join('html'); // /var/www/html/ $file = $base->join('html/index.php', trailingSeparator: false); // /var/www/html/index.php $file = $base->join('html/index.php', trailingSeparator: true); // /var/www/html/index.php/ // Можно передать массив, строку или Path $base->join(['assets', 'css']); // /var/www/assets/css/ $base->join(new Path('logs')); // /var/www/logs/
joinName(mixed $data): Path
Аналог join(), но принудительно устанавливает hasTrailingSeparator = false. Удобно для добавления имени файла:
$dir = new Path('/var/www/'); $file = $dir->joinName('index.php'); echo $file; // /var/www/index.php
Нормализация путей (конверсия относительных)
При создании, соединении и экспорте путь приводится к «актуальному» виду, как это делает обычная ОС:
- Сегмент
.и пустые сегменты нейтрализуются:foo/./bar→foo/bar. - Сегмент
..выталкивает предыдущий:a/b/../c→a/c. - Выше корня подняться нельзя. На корне
..для абсолютного пути отбрасывается (/foo→/), а для относительного — остаётся как ссылка на родителя (../fooостаётся../foo, какcd ..в оболочке).
Path::create('base')->join('dir')->join('..'); // base/ Path::create('/foo/bar')->join('..'); // /foo/ Path::create('foo')->join('..'); // '' (относительный корень) new Path('a/b/../c'); // a/c new Path('../foo'); // ../foo new Path('/..'); // /
Установка флагов
Все методы мутируют текущий объект и возвращают $this для цепочек вызовов.
setAbsolutePath(bool $is_present = true): Path
$path = new Path('foo/bar'); $path->setAbsolutePath(true); echo $path; // /foo/bar
setTrailingSeparator(bool $is_present = true): Path
$path = new Path('/var/www'); $path->setTrailingSeparator(true); echo $path; // /var/www/ (флаг уважается по умолчанию) echo $path->toString(false); // /var/www
setOptions(array $options): Path
Устанавливает сразу несколько флагов. Поддерживает ключи isAbsolute и hasTrailingSeparator:
$path->setOptions([ 'isAbsolute' => true, 'hasTrailingSeparator' => false, ]);
Неизвестные ключи игнорируются. Значение
nullтакже игнорируется (ключ должен присутствовать с непустым значением).
Проверка файловой системы
isDirectory(): bool
Возвращает true, если по данному пути существует директория.
if ((new Path('/var/log'))->isDirectory()) { /* ... */ }
isFile(): bool
Возвращает true, если путь указывает на существующий читаемый файл.
if ((new Path('/etc/hosts'))->isFile()) { /* ... */ }
makePath(int $access_rights = 0777): bool
Создаёт директорию рекурсивно (аналог mkdir -p). Возвращает true при успехе или если директория уже существует.
$created = (new Path('/tmp/app/cache'))->makePath(0755);
Внутренние свойства
| Свойство | Тип | Описание |
|---|---|---|
$atoms |
array |
Массив сегментов пути (['var', 'www', 'html']) |
$isAbsolutePath |
?bool |
Путь начинается с / |
$hasTrailingSeparator |
?bool |
Путь заканчивается на / |
URL-адреса
Класс работает только с файловыми путями. Легаси-поддержка URL (:// → :||-костыль)
вынесена из Path в отдельный класс Arris\Entity\Url (схема+хост — корень, join(),
нормализация ../.). Он не входит в состав пакета — используйте при необходимости
как самостоятельную заготовку.
Совместимость и требования
- PHP 8.2+
- Реализует интерфейс
PathInterface - Разделитель сегментов:
ATOM_SEPARATOR = '/'— используется для разбора, склейки и экспорта
Известные особенности поведения
toString()по умолчанию уважает внутренний флагhasTrailingSeparator; явныеtrue/falseпринудительно добавляют/снимают разделитель в выводе — флаг инстанса не мутирует.join()по умолчанию трактует данные как каталог (hasTrailingSeparator = true); для склейки пути к файлу передавайтеtrailingSeparator: false.joinName()всегда сбрасывает флаг вfalse.- Сегмент
.(точка) нейтрализуется при нормализации и не попадает в$atoms(раньше превращался во внутренний пустой атом''). - Пустой атом (
'') в середине массива сегментов при проходе черезvalidateAtomне добавляется в$atoms. - Публичное свойство
$atomsможно мутировать напрямую — но при экспорте (toString) атомы всё равно нормализуются, так что'..'/'.'не уйдут в итоговую строку. - Пустая строка и
'/'дают абсолютный корень:isAbsolutePath = true, пустой$atoms,toString()→/.hasTrailingSeparatorпри этом сбрасывается вfalse(на пустом пути флаг не имеет смысла).
Лицензия
MIT