Если вы хоть раз писали на PHP что-то серьёзнее «Hello world», то наверняка сталкивались с файлами: то картинку загрузить, то CSV-отчёт сгенерировать, то просто прочитать конфиг. В Yii2 для этого есть удобные инструменты, которые экономят кучу времени и нервов. В этой статье я покажу, как правильно работать с файловой системой в Yii2, чтобы код был чистым, безопасным и не разваливался при первом же переносе на другой сервер. Поехали!
Почему не стоит использовать PHP-функции напрямую
Казалось бы, что сложного? Взял file_get_contents, прочитал, записал. Но в реальном проекте всё упирается в детали: пути, права доступа, обработка ошибок, совместимость с окружением. Если писать велосипеды каждый раз, код превращается в кашу.
Yii2 предоставляет компонент yii\helpers\BaseFileHelper — это набор статических методов для самых частых операций. Он уже протестирован, учитывает кучу подводных камней и работает одинаково на Linux, Windows и macOS. Плюс, если нужно что-то особенное, вы всегда можете расширить его своим классом.
Вот простой пример: создать директорию, если её нет. Напрямую это делается так:
$path = '/var/www/uploads';
if (!is_dir($path)) {
mkdir($path, 0775, true);
}
А через Yii2 — одной строкой:
use yii\helpers\BaseFileHelper;
BaseFileHelper::createDirectory('/var/www/uploads');
Метод сам создаст все недостающие папки и выставит права. И не надо думать о мелочах.
BaseFileHelper::normalizePath() для приведения путей к единому виду. Это убережёт от проблем с разделителями на Windows.
Загрузка файлов через модель
Самая частая задача — дать пользователю загрузить аватарку или документ. В Yii2 это делается через модель и правило валидации. Смотрите, как элегантно.
Сначала в модели добавляем правило:
public function rules()
{
return [
[['avatar'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
];
}
А в контроллере обрабатываем загрузку:
public function actionUpload()
{
$model = new UploadForm();
if (Yii::$app->request->isPost) {
$model->load(Yii::$app->request->post());
$model->avatar = UploadedFile::getInstance($model, 'avatar');
if ($model->validate()) {
$path = Yii::getAlias('@webroot') . '/uploads/' . $model->avatar->baseName . '.' . $model->avatar->extension;
$model->avatar->saveAs($path);
// Дальше можно сохранить путь в БД
}
}
return $this->render('upload', ['model' => $model]);
}
Обратите внимание: UploadedFile — это специальный класс Yii2, который представляет загруженный файл. Он берёт на себя всю грязную работу: проверку размера, типа, перемещение во временную папку.
Работа с директориями и путями
В Yii2 есть замечательная функция Yii::getAlias(). Она позволяет не хардкодить пути, а использовать символические имена. Например, @webroot — это корень веб-сервера, @app — корень приложения, @runtime — папка для временных файлов.
Это очень удобно: если вы переедете на другой сервер или поменяете структуру, вам не придётся переписывать код. Просто поменяете алиасы в конфиге.
Вот пример, как получить абсолютный путь до папки загрузок:
$uploadPath = Yii::getAlias('@webroot') . '/uploads';
BaseFileHelper::createDirectory($uploadPath);
А если нужно проверить, существует ли файл, и получить его размер, то:
$file = Yii::getAlias('@app/files/report.pdf');
if (file_exists($file)) {
$size = filesize($file); // в байтах
echo 'Размер: ' . Yii::$app->formatter->asShortSize($size);
}
Удаление и перемещение файлов
Удалять файлы тоже нужно уметь правильно. Просто unlink() — не всегда хорошая идея, потому что файл может быть занят или не существовать. Yii2 предлагает более безопасный способ.
use yii\helpers\FileHelper;
$file = Yii::getAlias('@webroot') . '/uploads/old_photo.jpg';
if (FileHelper::unlink($file)) {
// файл удалён
} else {
// ошибка — можно залогировать
}
Перемещение делается так же просто:
FileHelper::move($source, $destination);
Метод сам проверит, что исходный файл существует, и создаст целевую директорию, если нужно.
Советы по безопасности
Работа с файлами — это всегда риск. Вот несколько правил, которые уберегут вас от беды.
- Никогда не доверяйте имени файла от пользователя. Вместо
baseNameлучше генерировать случайное имя черезuniqid()илиYii::$app->security->generateRandomString(). - Проверяйте MIME-тип — расширение могут подделать. В Yii2 для этого есть
FileHelper::getMimeType(). - Ограничивайте размер файла через правила валидации (атрибут
maxSize). - Храните загруженные файлы вне веб-корня, если они не должны быть доступны напрямую. Тогда доступ к ним можно контролировать через контроллер.
@app/uploads, а не в @webroot/uploads. И отдавайте через специальный экшен с проверкой прав.
Что в итоге
Yii2 даёт удобные инструменты для работы с файлами: BaseFileHelper, алиасы, валидацию загрузок. Используйте их, чтобы не изобретать велосипеды и избежать типичных ошибок.
Главное, что стоит запомнить:
- Всегда используйте алиасы для путей.
- Проверяйте файлы перед сохранением.
- Генерируйте безопасные имена.
- Не забывайте про права доступа.
Теперь вы можете смело работать с файлами в Yii2, не боясь сюрпризов. Удачи в кодинге!


