Компонент Filesystem
Дата оновлення перекладу 2024-05-02
Компонент Filesystem
Компонент Filesystem надає незалежні від платформ інструменти для операцій файлових систем та маніпуляцій зі шляхами файлів/каталогів.
Установка
1
$ composer require symfony/filesystem
Note
Якщо ви встановлюєте цей компонент поза додатком Symfony, вам потрібно підключити
файл vendor/autoload.php
у вашому коді для включення механізму автозавантаження
класів, наданих Composer. Детальніше можна прочитати у цій статті.
Використання
Компонент містить два основних класи під назвами Filesystem і Path:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
use Symfony\Component\Filesystem\Filesystem;
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
. Ви можете використати другий аргумент, щоб встановити
ваш власний режим:
1
$fileSystem->mkdir('/tmp/photos', 0700);
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
Note
Ця функція ігнорує вже існуючі каталоги.
exists
exists() перевіряє наявність
одного або більше файлів чи каталогів та повертає false
, якщо якісь з них
відсутні:
1 2 3 4 5 6
// якщо цей каталог з цим абсолютним шляхом існує, повернути true
$fileSystem->exists('/tmp/photos');
// если rabbit.jpg інсує, bottle.png не існує, повернути false
// не абсолютні шляхи є відносними до каталогу, де знаходиться запущений скрипт PHP
$fileSystem->exists(array('rabbit.jpg', 'bottle.png'));
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
copy
copy() робить копію одного файлу (використайте mirror(), щоб копіювати каталоги). Якщо ціль вже існує, то файл копіюється лише якщо дата змінення джерела пізніша, ніж у цілі. Цю поведінку можна перевизначити третім булевим аргументом:
1 2 3 4 5
// працює лише якщо image-ICC було змінено після image.jpg
$fileSystem->copy('image-ICC.jpg', 'image.jpg');
// image.jpg буде перевизначено
$fileSystem->copy('image-ICC.jpg', 'image.jpg', true);
touch
touch() встанвлює доступ та час зміни файлу. Поточний час використовується за замовчуванням. Ви можете встановити ваш власний за допомогою другого аргументу. Третій аргумент - це час доступу:
1 2 3 4 5 6
// встанвлює час зміни у поточній відмітці часу
$fileSystem->touch('file.txt');
// встановлює час зміни на 10 секунд у майбутньому
$fileSystem->touch('file.txt', time() + 10);
// встановлює час зміни на 10 секунд у минулому
$fileSystem->touch('file.txt', time(), time() - 10);
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
chown
chown() змінює власника файлу. Третій аргумент - рекурсивна булева опція:
1 2 3 4
// встановлює власника відео lolcat як www-data
$fileSystem->chown('lolcat.mp4', 'www-data');
// рекурсивно змінює власника каталогу відео
$fileSystem->chown('/video', 'www-data', true);
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
chgrp
chgrp() змінює групу файлу. Третій аргумент - рекурсивна булева опція:
1 2 3 4
// встановлює групу відео lolcat як nginx
$fileSystem->chgrp('lolcat.mp4', 'nginx');
// рекурсивно змінює групу каталогу відео
$fileSystem->chgrp('/video', 'nginx', true);
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
chmod
chmod() змінює режим або дозволи файлу. Четвертий аргумент - рекурсивна булева опція:
1 2 3 4
// встановлює режим відео 0600
$fileSystem->chmod('video.ogg', 0600);
// рекурсивно змінює режим каталогу src
$fileSystem->chmod('src', 0700, 0000, true);
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
remove
remove() видаляє файли, каталоги та симовльні посилання:
1
$fileSystem->remove(array('symlink', '/path/to/directory', 'activity.log'));
Note
Ви можете передати масив або будь-який traversable обʼєкт в якості першого аргументу.
rename
rename() змінює імʼя одного файлу або каталогу:
1 2 3 4 5 6
// переіменовує файл
$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);
symlink
symlink() створює символьне посилання від цілі до напрямку. Якщо файлова система не підтримує символьні поислання, доступний третій булевий аргумент:
1 2 3 4 5
// створює символьне посилання
$fileSystem->symlink('/path/to/source', '/path/to/destination');
// дублює каталог джерела, якщо файлова система не
// підтримує символьні посилання
$fileSystem->symlink('/path/to/source', '/path/to/destination', true);
readlink
readlink() читає посилання цілей.
Метод readlink(), наданий компонентом Filesystem, завжди поводить себе однаково на всіх операційних системах (на відміну від функції PHP readlink):
1 2 3 4 5 6
// повертає наступну пряму ціль посилання, не розглядаючи існування цілі
$fileSystem->readlink('/path/to/link');
// повертає абсолютну повністю дозволену фінальну версію цілі
// (якщо були вкладені посилання, вони дозволені)
$fileSystem->readlink('/path/to/link', true);
Його поведінка наступна:
1
public function readlink($path, $canonicalize = false)
Коли
$canonicalize
-false
:- якщо
$path
не існує, або не є посиланням, то повертаєтьсяnull
. - якщо
$path
- посилання, повертається наступна пряма ціль посилання, не розглядаючи існування цілі.
- якщо
Коли
$canonicalize
-true
:- якщо
$path
не існує, то повертаєтьсяnull
. - якщо
$path
існує, то повертається його абсолютна повністю дозволена фінальна версія.
- якщо
Note
Якщо ви хочете канонікалізувати шлях, не перевіряючи його існування, ви можете використати замість цього метод canonicalize().
makePathRelative
makePathRelative() бере два абсолютних шляхи та повертає відносний шлях від другого шляху до першого:
1 2 3 4 5 6 7
// повертає '../'
$fileSystem->makePathRelative(
'/var/lib/symfony/src/Symfony/',
'/var/lib/symfony/src/Symfony/Component'
);
// повертає 'videos/'
$fileSystem->makePathRelative('/tmp/videos', '/tmp')
mirror
mirror() копіює весь зміст каталогу джерела у цільовий (використовуйте метод copy(), щоб скопіювати поодинокі файли):
1
$fileSystem->mirror('/path/to/source', '/path/to/target');
isAbsolutePath
isAbsolutePath() повертає
true
, якщи даний шлях абсолютний, false
- у всіх інших випадках:
1 2 3 4 5 6 7 8
// повертає true
$fileSystem->isAbsolutePath('/tmp');
// повертає true
$fileSystem->isAbsolutePath('c:\\Windows');
// повертає false
$fileSystem->isAbsolutePath('tmp');
// повертає false
$fileSystem->isAbsolutePath('../dir');
tempnam
tempnam() створює тимчасовий файл з унікальним імʼям та повертає його шлях, або викилкає виключення за умови невдачі:
1 2 3 4
// повертає шлях на кшталт: /tmp/prefix_wyjgtF
$filesystem->tempnam('/tmp', 'prefix_');
// повертає шлях на кшталт: /tmp/prefix_wyjgtF.png
$filesystem->tempnam('/tmp', 'prefix_', '.png');
dumpFile
dumpFile() зберігає даний зміст у файл. Це робиться автоматично: він спочатку записує тимчасовий файл, а потім переміщує його у нову локацію файлу, коли він завершений. Це означає, що користувач завжди бачитиме або повний старий файл, або повний новий файл (але ніколи не частково написаний файл):
1
$fileSystem->dumpFile('file.txt', 'Hello World');
Файл file.txt
тепер містить Hello World
.
appendToFile
appendToFile() додає новий зміст наприкінці якогось файлу:
1 2 3
$fileSystem->appendToFile('logs.txt', 'Email sent to user@example.com');
// третій аргумент повідомляє, чи має файл знову бути заблокований при внесенні записів у нього
$filesystem->appendToFile('logs.txt', 'Email sent to user@example.com', true);
Якщо або файл, або каталог, що його містить, не існує, то цей метод створює їх перед додаванням змісту.
readFile
7.1
Метод readFile()
було представлено в Symfony 7.1.
readFile() повертає весь зміст файлу у вигляді рядка. На відміну від функції file_get_contents з PHP, вона генерує виключення, коли вказаний шлях файлу не є читабельним та при передачі шляху до каталогу замість файлу:
1
$contents = $filesystem->readFile('/some/path/to/file.txt');
Змінна $contents
тепер зберігає весь зміст файлу file.txt
.
Утиліти для маніпуляцій зі шляхами
Робота зі шляхами файлів зазвичай викликає деякі труднощі:
- Різниця платформ: шляхі файлів виглядають по-різному на різних платфоромах. Шляхи файлів UNIX починаються зі слешу ("/"), в той час як шляхи файлів Windows починаються з системного диску ("C:"). UNIX використовує слеш праворуч, в той час як Windows за замовчуванням використовує слеш ліворуч.
- Абсолютні/відносні шляхи: веб-додаткам часто необхідно розбиратися з абсоллютними та відносними шляхами. Перетворення одних на інші правильним чином є складним та стомливим.
Path надає службові методи для роботи з такими проблемами.
Канонікалізація
Повертає найкоротше імʼя шляху, еквівалентне заданому шляху. Ітеративно застосовує наступні правила до тих пір, поки подальша обробка не стане неможливою:
- видаляються сегменти ".";
- вирішуються сегменти "..";
- слеші ліворуч ("") перетворюються на слеші праворуч ("/");
- кореневі шляхи ("/" і "C:/") завжди закінчуються слешем;
- некореневі шляхи ніколи не закінчуються слешем;
- схеми (такі як "phar://") залишаються;
- " " замінюються домашнім каталогом користувача.
Ви можете канонікалізувати шлях за допомогою canonicalize():
1 2
echo Path::canonicalize('/var/www/vhost/webmozart/../config.ini');
// => /var/www/vhost/config.ini
Ви можете передати абсолютні та відносні шляхи методу canonicalize(). Коли передається відносний шлях, сегменти ".." на початку шляху залишаються:
1 2
echo Path::canonicalize('../uploads/../config/config.yaml');
// => ../config/config.yaml
Спотворені шляхи повертаються незміненими:
1 2
echo Path::canonicalize('C:Programs/PHP/php.ini');
// => C:Programs/PHP/php.ini
Перетворення абсолютних/відносних шляхів
Абсолютні/відносні шляхи можуть бути перетворені за допомогою методів makeAbsolute() та makeRelative().
Метод makeAbsolute() очікує відносного шляху та базового шляху, на якому заснувати відносний шлях:
1 2
echo Path::makeAbsolute('config/config.yaml', '/var/www/project');
// => /var/www/project/config/config.yaml
Якщо абсолютний шлях передано у першому аргументі, абсолютний шлях повертається незміненим:
1 2
echo Path::makeAbsolute('/usr/share/lib/config.ini', '/var/www/project');
// => /usr/share/lib/config.ini
Метод розвʼязує сегменти "..", якщо такі були:
1 2
echo Path::makeAbsolute('../config/config.yaml', '/var/www/project/uploads');
// => /var/www/project/config/config.yaml
Цей метод дуже корисний, якщо ви хочете мати можливість приймати відносні шляхи (наприклад, відносні по відношенню до кореневого каталогу вашого проекта) і абсолютні шляхи водночас.
makeRelative() - це інверсована операція makeAbsolute():
1 2
echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project');
// => config/config.yaml
Якщо шлях не знаходиться у базовому шляху, метод додасть сегменти "..", де це необхідно:
1 2
echo Path::makeRelative('/var/www/project/config/config.yaml', '/var/www/project/uploads');
// => ../config/config.yaml
Використайте makeAbsolute() та makeRelative(), щоб перевірити, чи є шлях абсолютним чи відносним:
1 2
Path::isAbsolute('C:\Programs\PHP\php.ini')
// => true
Всі чотири методи внутрішньо канонікалізують переданий шлях.
Пошук найдовших спільних базових шляхів
Коли ви зберігаєте абсолютні шляхи файлів у файловій системі, це призводить до великої кількості дубльованої інформації:
1 2 3 4 5 6 7
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(), щоб побачити список шляхів для загального базового шляху:
1 2 3 4 5 6 7 8
Path::getLongestCommonBasePath(
'/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'
);
// => /var/www/vhosts/project/httpdocs
Використайте цей шлях разом з makeRelative(), щоб скоротити збережені шляхи:
1 2 3 4 5 6 7 8 9
$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(), щоб протестувати, чи є шлях базовим:
1 2 3 4 5 6 7 8
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()
не приймає зворотні слеші на UNIXdirname("C:/Programs")
повертає "C:", а не "C:/"dirname("C:/")
повертає ".", а не "C:/"dirname("C:")
повертає ".", а не "C:/"dirname("Programs")
повертає ".", а не ""dirname()
не канонікалізує результат
getDirectory() виправляє ці недоліки:
1 2
echo Path::getDirectory("C:\Programs");
// => C:/
Крім того, ви можете використати getRoot(), щоб отримати корінь шляху:
1 2 3 4 5
echo Path::getRoot("/etc/apache2/sites-available");
// => /
echo Path::getRoot("C:\Programs\Apache\Config");
// => C:/
Обробка помилок
Коли щось йде не так, викликається виключення, що реалізує ExceptionInterface або IOExceptionInterface.
Note
Якщо створення каталогу проходить неуспішно, викликається IOException.