Дата обновления перевода 2021-12-26

Компонент Filesystem

Компонент Filesystem предоставляет независимые от платформ инструменты для операций файловых систем и для манипуляций с путями файлов/каталогов.

Установка

1
$ composer require symfony/filesystem

Note

If you install this component outside of a Symfony application, you must require the vendor/autoload.php file in your code to enable the class autoloading mechanism provided by Composer. Read this article for more details.

Использование

Компонент содержит два основных класса, под названиями Filesystem и Path:

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
use Symfony\Component\Filesystem\Path;

$fileSystem = new Filesystem();

try {
    $filesystem->mkdir(
        Path::normalize(sys_get_temp_dir().'/'.random_int(0, 1000)),
    );
} catch (IOExceptionInterface $exception) {
    echo "An error occurred while creating your directory at ".$exception->getPath();
}

Утилиты файловой системы

mkdir

mkdir() создаёт каталог рекурсивно. В файловых системах POSIX, каталоги создаются со значением режима по умолчанию 0777. Вы можете использовать второй аргумент, чтобы установить ваш собственный режим:

$fileSystem->mkdir('/tmp/photos', 0700);

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

Note

Эта функция игнорирует уже существующие каталоги.

Note

Текущий umask влияет на разрешения каталога. Установите umask для вашего веб-сервера, используйте функцию PHP umask или используйте функцию chmod после создания каталога.

exists

exists() проверяет наличие одного или болеефайлоа или каталогов и возвращает false, если какие-либо из них отсутствуют:

// если этот каталог с этим абсолютным путём существует, вернуть true
$fileSystem->exists('/tmp/photos');

// если rabbit.jpg существует, bottle.png не существует, вернуть false
// не абсолютные пути являются относительными к каталогу, где находится запущенный скрипт PHP
$fileSystem->exists(array('rabbit.jpg', 'bottle.png'));

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

copy

copy() делает копию одного файла (используйте mirror(), чтобы копировать каталоги). Если цель уже существует, то файл копируется только, если дата изменения источника позже, чем у цели. Это поведение можно переопределить третьим булевым аргументом:

// работает только, если image-ICC было изменено после image.jpg
$fileSystem->copy('image-ICC.jpg', 'image.jpg');

// image.jpg будет переопределено
$fileSystem->copy('image-ICC.jpg', 'image.jpg', true);

touch

touch() устанавливает доступ и время изменения файла. Текущее время используется по умолчанию. Вы можете установить ваше собственное с помощью второго аргумента. Третий аргумент - это время доступа:

// устанавливает время изменения в текущей отметке времени
$fileSystem->touch('file.txt');
// устанавливает время изменения на 10 секунд в будущем
$fileSystem->touch('file.txt', time() + 10);
// устанавливает время изменения на 10 секунд в прошлом
$fileSystem->touch('file.txt', time(), time() - 10);

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

chown

chown() изменяет владельца файла. Третий аргумент - рекурсивная булева опция:

// устанавливает владельца видео lolcat как www-data
$fileSystem->chown('lolcat.mp4', 'www-data');
// рекурсивно изменяет владельца каталога видео
$fileSystem->chown('/video', 'www-data', true);

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

chgrp

chgrp() изменяет группу файла. Третий аргумент - рекурсивная булева опция:

// устанавливает группу видео lolcat как nginx
$fileSystem->chgrp('lolcat.mp4', 'nginx');
// рекурсивно изменяет группу каталога видео
$fileSystem->chgrp('/video', 'nginx', true);

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

chmod

chmod() изменяет режим или разрешения файла. Четвертый аргумент - рекурсивная булева опция:

// устанавливает режим видео 0600
$fileSystem->chmod('video.ogg', 0600);
// рекурсивно изменяет режим каталога src
$fileSystem->chmod('src', 0700, 0000, true);

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

remove

remove() удаляет файлы, каталогы и сивольные ссылки:

$fileSystem->remove(array('symlink', '/path/to/directory', 'activity.log'));

Note

Вы можете передать массив или любой traversable объект в качестве первого аргумента.

rename

rename() изменяет имя одного файла или каталога:

// переименовывает файл
$fileSystem->rename('/tmp/processed_video.ogg', '/path/to/store/video_647.ogg');
// переименовывает каталог
$fileSystem->rename('/tmp/files', '/path/to/store/files');
// если цель уже существует, для перезаписи доступен третий булев аргумент.
$filesystem->rename('/tmp/processed_video2.ogg', '/path/to/store/video_647.ogg', true);

makePathRelative

makePathRelative() берёт два абсолютных пути и возвращает относительный путь от второго пути к первому:

// возвращает '../'
$fileSystem->makePathRelative(
    '/var/lib/symfony/src/Symfony/',
    '/var/lib/symfony/src/Symfony/Component'
);
// возвращает 'videos/'
$fileSystem->makePathRelative('/tmp/videos', '/tmp')

mirror

mirror() копирует всё содержание каталога источника в целевой (используйте метод copy(), чтобы скопировать одиночные файлы):

$fileSystem->mirror('/path/to/source', '/path/to/target');

isAbsolutePath

isAbsolutePath() возвращает true, если данный путь абсолютный, false - во всех других случаях:

// возвращает true
$fileSystem->isAbsolutePath('/tmp');
// возвращает true
$fileSystem->isAbsolutePath('c:\\Windows');
// возвращает false
$fileSystem->isAbsolutePath('tmp');
// возвращает false
$fileSystem->isAbsolutePath('../dir');

tempnam

tempnam() создает временный файл с уникальным именем, и возвращает его путь, или вызывает исключение при неудаче:

// возвращает путь вроде : /tmp/prefix_wyjgtF
$filesystem->tempnam('/tmp', 'prefix_');
// возвращает путь вроде : /tmp/prefix_wyjgtF.png
$filesystem->tempnam('/tmp', 'prefix_', '.png');

New in version 5.1: Опция устанавливать суффикс в tempnam() была представлена в Symfony 5.1.

dumpFile

dumpFile() сохраняет данное содержание в файл. Это делается автоматически: он вначале записывает временный файл и потом перемещает его в новую локацию файла, когда он закончен. Это означает, что пользовательвсегда будет видеть либо полный старый файл, либо полный новый файл (но никогда - частично написанный файл):

$fileSystem->dumpFile('file.txt', 'Hello World');

Файл file.txt теперь содержит Hello World.

appendToFile

appendToFile() добавляет новое содержание в конце некоторого файла:

$fileSystem->appendToFile('logs.txt', 'Email sent to [email protected]');
// третий аргумент сообщает, должен ли файл снова быть заблокирован при внесении записей в него
$filesystem->appendToFile('logs.txt', 'Email sent to [email protected]', true);

Если либо файл, либо каталог, содержащий его, не существует, то этот метод создаёт их перед добавлением содержания.

New in version 5.4: Третий аргумент appendToFile() был представлен в Symfony 5.4.

Утилиты для манипуляций с путями

New in version 5.4: Класс Path был представлен в Symfony 5.4.

Работа с путями файлов обычно вызывает некоторые сложности:

  • Разница платформ: пути файлов выглядят по-разному на разных платформах. Пути файлов UNIX начинаются со слеша (“/”), в то время, как пути файлов Windows начинаются с систмного диска (“C:”). UNIX использует слеш вправо, в то время, как Windows по умолчанию использует слеш влево.
  • Абсолютные/относительные пути: веб-приложениям часто необходимо разбираться с абсолютными и относительными путями. Преобразование одних в другие правильным образом является сложным и утомительным.

Path предоставляет служебные методы для работы с такими проблемами.

Каноникализация

Возвращает самое короткое имя пути, эквивалентное заданному пути. Итеративно применяет следующие правила до тех пор, пока дальнейшая обработка не станет невозможной:

  • удаляются сегменты “.”;
  • разрешаются сегменты “..”;
  • слеши влево (“”) преобразуются в слеши вправо (“/”);
  • корневые пути (“/” и “C:/”) всегда заканчиваются слешем;
  • некорневые пути никогда не заканчиваются слешем;
  • схемы (такие, как “phar://”) остаются;
  • “~” заменяются домашним каталогом пользователя.

Вы можете каноникализировать путь с помощью canonicalize():

echo Path::canonicalize('/var/www/vhost/webmozart/../config.ini');
// => /var/www/vhost/config.ini

Вы можете передать абсолютные и относительные пути методу canonicalize(). Когда передается относительный путь, сегменты “..” в начале пути остаются:

echo Path::canonicalize('../uploads/../config/config.yaml');
// => ../config/config.yaml

Искаженые пути возвращаются неизмененными:

echo Path::canonicalize('C:Programs/PHP/php.ini');
// => C:Programs/PHP/php.ini

Преобразование абсолютных/относительных путей

Абсолютные/относительные пути могут быть преобразованы с помощью методов makeAbsolute() и makeRelative().

Метод makeAbsolute() ожидает относительный путь и базовый путь, на котором основать относительный путь:

echo Path::makeAbsolute('config/config.yaml', '/var/www/project');
// => /var/www/project/config/config.yaml

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

echo Path::makeAbsolute('/usr/share/lib/config.ini', '/var/www/project');
// => /usr/share/lib/config.ini

Метод разрешает сегменты “..”, если такие были:

echo Path::makeAbsolute('../config/config.yaml', '/var/www/project/uploads');
// => /var/www/project/config/config.yaml

Этот метод очень полезен, если вы хотите иметь возможность принимать относительные нути (к примеру, относительные по отношению к корневому каталогу вашего проекта) и абсолютные пути одновременно.

makeRelative() - это инверсированная операция makeAbsolute():

echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project');
// => config/config.yaml

Если путь не находится в базовом пути, метод добавит сегменты “..”, где необходимо:

echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project/uploads');
// => ../config/config.yaml

Используйте makeAbsolute() и makeRelative(), чтобы проверить, является путь относительным или абсолютным:

Path::isAbsolute('C:\Programs\PHP\php.ini')
// => true

Все четыре метода внутренне каноникализируют переданный путь.

Поиск наиболее длинных базовых путей

Когда вы храните абсолютные пути файлов в файловой системе, это приводит к большому количеству дублированной информации:

return [
    '/var/www/vhosts/project/httpdocs/config/config.yaml',
    '/var/www/vhosts/project/httpdocs/config/routing.yaml',
    '/var/www/vhosts/project/httpdocs/config/services.yaml',
    '/var/www/vhosts/project/httpdocs/images/banana.gif',
    '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
];

Количество дублированной информации особенно заметно при хранении большого количества путей. Вы можете использовать getLongestCommonBasePath(), чтобы увидеть список путей для общего базового пути:

$paths = [
    '/var/www/vhosts/project/httpdocs/config/config.yaml',
    '/var/www/vhosts/project/httpdocs/config/routing.yaml',
    '/var/www/vhosts/project/httpdocs/config/services.yaml',
    '/var/www/vhosts/project/httpdocs/images/banana.gif',
    '/var/www/vhosts/project/httpdocs/uploads/images/nicer-banana.gif',
];

Path::getLongestCommonBasePath($paths);
// => /var/www/vhosts/project/httpdocs

Используйте этот пусть вместе с makeRelative(), чтобы сократить сохраненные пути:

$bp = '/var/www/vhosts/project/httpdocs';

return [
    $bp.'/config/config.yaml',
    $bp.'/config/routing.yaml',
    $bp.'/config/services.yaml',
    $bp.'/images/banana.gif',
    $bp.'/uploads/images/nicer-banana.gif',
];

getLongestCommonBasePath() всегда возвращает каноникальные пути.

Используйте isBasePath(), чтобы протестировать, является ли путь базовым:

Path::isBasePath("/var/www", "/var/www/project");
// => true

Path::isBasePath("/var/www", "/var/www/project/..");
// => true

Path::isBasePath("/var/www", "/var/www/project/../..");
// => false

Поиск каталогов/корневых каталогов

PHP предлагает функцию dirname, чтобы получить путь каталога пути файла. Этот метод имеет несколько особенностей:

- `dirname()` не принимает обратные слеши на UNIX
- `dirname("C:/Programs")` возвращает "C:", а не "C:/"
- `dirname("C:/")` возвращает ".", а не "C:/"
- `dirname("C:")` возвращает ".", а не "C:/"
- `dirname("Programs")` возвращает ".", а не ""
- `dirname()` не каноникализирует результат

getDirectory() исправляет эти недостатки:

echo Path::getDirectory("C:\Programs");
// => C:/

Кроме того, вы можете использовать getRoot(), чтобы получить корень пути:

echo Path::getRoot("/etc/apache2/sites-available");
// => /

echo Path::getRoot("C:\Programs\Apache\Config");
// => C:/

Обработка ошибок

Когда что-то идёт не так, вызывается исключение, реализующее ExceptionInterface или IOExceptionInterface.

Note

Если создание каталога проходит неуспешно, вызывается IOException.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.