Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arris\Entity\Path

Утилитарный класс для построения и манипуляции файловыми путями.

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///bazfoo/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/./barfoo/bar.
  • Сегмент .. выталкивает предыдущий: a/b/../ca/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

Releases

Contributors

Languages