Yii2 где хранить файлы
Загрузка файлов в Yii, обычно, выполняется при помощи класса yii\web\UploadedFile, который представляет каждый загруженный файл в виде объекта UploadedFile . Используя yii\widgets\ActiveForm и модели можно легко создать безопасный механизм загрузки файлов.
Как и в случае с обработкой текстового ввода, для загрузки файла можно создать класс модели и использовать его атрибут для хранения экземпляра объекта UploadedFile , содержащего параметры загруженного файла. Так же, возможно использование правил валидации модели для проверки загруженного файла. Например,
В примере выше атрибут imageFile используется для хранения экземпляра загруженного файла. Правило валидации file , которое, при помощи валидатора yii\validators\FileValidator, проверяет расширение загруженного файла на соответствие с png или jpg . Метод upload() выполняет валидацию и сохраняет загруженный файл на сервере.
Валидатор file позволяет проверять расширение, размер, тип MIME и другие параметры загруженного файла. Подробности в разделе Встроенные валидаторы.
Tip: При загрузке изображений лучше использовать соответствующий валидатор image . Данный валидатор реализован классом yii\validators\ImageValidator и позволяет проверить корректность загруженного изображения при помощи расширения Imagine.
Теперь можно создать представление, отображающее поле загрузки файла:
Важно помнить, что для корректной загрузки файла, необходим параметр формы enctype . Метод fileInput() выведет тег <input type="file"> , позволяющий пользователю выбрать файл для загрузки.
Tip: начиная с версии 2.0.8, fileInput автоматически добавляет к форме свойство enctype , если в ней есть поле для загрузки файла.
Теперь напишем код действия контроллера, который объединит модель и представление.
При получении данных, отправленных из формы, для создания из загруженного файла экземпляра объекта UploadedFile , вызывается метод yii\web\UploadedFile::getInstance(). Далее всю работу по валидации и сохранению загруженного файла на сервере берет на себя модель.
Для загрузки нескольких файлов достаточно внести в предыдущий код несколько небольших изменений.
Сначала нужно добавить в правило валидации file параметр maxFiles для ограничения максимального количества загружаемых одновременно файлов. Установка maxFiles равным 0 означает снятие ограничений на количество файлов, которые могут быть загружены одновременно. Максимально разрешенное количество одновременно закачиваемых файлов также ограничивается директивой PHP max_file_uploads , и по умолчанию равно 20. Метод upload() нужно изменить для сохранения загруженных файлов по одному.
В представлении, в вызов метода fileInput() , нужно добавить параметр multiple для того, чтобы поле input позволяло выбирать несколько файлов одновременно. Необходимо изменить imageFiles на imageFiles[] чтобы атрибут передавался в виде массива:
В действии контроллера нужно заменить вызов UploadedFile::getInstance() на UploadedFile::getInstances() для присвоения атрибуту модели imageFiles массива объектов UploadedFile .
Где и как лучше хранить изображения yii2 advanced
Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.Где и как лучше хранить изображения yii2 advanced
Использую yii2 advanced, где лучше создавать папку для хранения изображений? В backend/web/uploads/.. и в на фронте как-то обращаться к папке бекенд @backend/web/uploads. ?Или еще видел, что делают в папке common , и ложат тудаже файл .htacces с таким правилом RewriteRule ^(.*)$ /frontend/web/index.php.
Кто как делает? Поделитесь опытом хранить где угодно, где логичнее (логичнее хранить во фронте или отдельном поддомене для статики). Урлы формировать абсолютные, независимо от того, в каком приложении выводите картинку.
согласен, хранить можно где угодна. Где логичнее там и хранить. Если храните папку в backend/web/uploads то в frontend/web/ создайте символическую ссылку, которая будет смотреть на backend-овское.
ln -s backend/web/uploads frontend/web/uploads
хранить можно хоть где, но я бы не стал лишний раз светить backend урл (на нем же админка)специалисты если нужно итак найдут, зато для всех остальных не будет лишнего повода пытаться ломиться куда не следует
и не нужно абсолютные урлы делать. Если вдруг потербуется зайти на сайт по техническому имени, при недостопности основного по какой-то причине, или смене домена - будут проблемы. sanzhikee писал(а): согласен, хранить можно где угодна. Где логичнее там и хранить. Если храните папку в backend/web/uploads то в frontend/web/ создайте символическую ссылку, которая будет смотреть на backend-овское.
в посте ссылка позволяет обращаться к папке фронтенд через бэкенд
т.е. если рассмотреть предложенный вариант
то картинки в адмминке заливаются в бэкенд папку.
урл в БД сохраняется относительный
и картинку можно открывать как в бэкенд так и во фронтенд. она автоматом будет видна и там и там через относительный урл
я у себя тоже через символическую ссылку делал.
kwasti писал(а): в посте ссылка позволяет обращаться к папке фронтенд через бэкенд
т.е. если рассмотреть предложенный вариант
то картинки в адмминке заливаются в бэкенд папку.
урл в БД сохраняется относительный
и картинку можно открывать как в бэкенд так и во фронтенд. она автоматом будет видна и там и там через относительный урл
Загрузка файлов в Yii выполняется с помощью модели-формы, её правил валидации и некоторого кода в контроллере. Давайте посмотрим подробнее, что необходимо для загрузки файлов.
Загрузка одного файла
Для начала требуется создать модель, которая будет обрабатывать загрузку файлов. Создайте models/UploadForm.php со следующим содержанием:
В коде что выше, мы создали модель UploadForm с свойством file , которое станет в HTML форме <input type="file"> . В правилах валидации это свойство описывается правилом file , которое используется [[yii\validators\FileValidator|FileValidator]].
Вид формы
Далее создайте вид, который будет выводить форму:
'enctype' => 'multipart/form-data' необходимо для того, чтобы форма поддерживала отправку файлов. fileInput() формирует файловый элемент формы.
Контроллер
Теперь создайте контроллер, который соединит вид формы и модель:
Вместо model->load(. ) мы используем UploadedFile::getInstance(. ) . Так как [[\yii\web\UploadedFile|UploadedFile]] не запускает процесс валидации модели, а только предоставляет информацию о загруженном файле. Поэтому необходимо произвести валидацию самостоятельно, через $model->validate() , которая вызовет [[yii\validators\FileValidator|FileValidator]]. Валидатор ожидает свойство, которое содержит информацию о загружаемом файле - вы это можете увидеть во внутреннем коде этого валидатора:
Если валидация пройдена успешна, то сохраняем файл:
Если вы используете "basic" шаблона приложения, то директория uploads должна быть создана внутри web .
Всё. Откройте форму и попробуйте загрузить файл. Он должен загрузиться в basic/web/uploads .
Валидация
Очень часто требуется разрешить загрузку только определённых файлов или установить обязательную загрузку. Ниже мы рассмотрим некоторые общие настройки правила file .
Обязательная загрузка файла
Если требуется обязательная загрузка файла, используйте skipOnEmpty :
тип MIME
Разумно проверять тип загружаемого файла. Для этого FileValidator имеет свойство $extensions :
По-умолчанию, эта проверка будет также проверять MIME-тип данных, в соответствии с расширением. Для gif это будет image/gif , для jpg - image/jpeg .
Обратите внимание, что некоторые MIME-типы могут быть определены неверно через fileinfo, расширение PHP, которое использует FileValidator. Например, csv файлы будут определены как text/plain вместо корректного text/csv . Вы можете отключить такое поведение через установку свойства checkExtensionByMimeType в false и указать корректный MIME-тип вручную:
Свойства изображений
Для загрузки изображений вам может пригодиться валидатор [[yii\validators\ImageValidator|ImageValidator]]. Он проверяет является ли файл изображением, которое затем может быть обработано или сохранено с помощью Imagine Extension.
Загрузка нескольких файлов
Если вам нужно загрузить несколько файлов одновременно, то необходимо внести некоторые корректировки.
Изменения внесены в строку
Есть два отличия в контроллере от загрузки одного файла. Во-первых используется UploadedFile::getInstances($model, 'file'); вместо UploadedFile::getInstance($model, 'file'); . Первый возвратит информацию обо всех загруженных файлах, в то время как, как второй вернёт информацию только об одном загруженном файле. Во-вторых отличие в том, что применяется foreach для сохранения каждого файла.
Загрузка файлов в yii2 осуществляется через класс yii\web\UploadedFile. Для безопасной загрузки файла необходимо использовать стандартный функционал ActiveForm и моделей с заготовленными правилами валидации.
Стандартная реализация
На официальном сайте Yii2 приводится статья, следуя которой можно реализовать стандартный механизм загрузки файла на сайт. Следует заметить, что для загрузки файла создается собственная модель с правилами валидации, в качестве ответа $model->upload() должен возвратить не только true или false, а, например, название файла.
- при росте проекта будет большая куча файлов, расположенных в одной папке, либо придется "плодить" большое количество моделей, ответственных за загрузку файлов.
Использование actions и виртуальной переменной
В данном примере понадобятся расширения yii2-file-kit и yii2-widget-fileinput.
Создадим виртуальную переменную $mainPicture в модели:
В web.config регистрируем компонент
В контроллере, который занимается созданием экземпляра articles (в бекенде) указываем actions:
Функция create примет вид:
Поле загрузки файла в форме создания статьи _form:
В данном случае, сохранение названия файла проходит через виртуальную переменную mainPicture в контроллере.
Обратите внимание на то, что используются события виджета FileInput.
Использование единого хранилища.
Данный способ отличается от предыдущего тем, что в таблице articles будем хранить не название файла, а его id. При такой реализации, в одной таблице базы данных будем хранить все загружаемые файлы, следовательно, для загрузки файлов можно будет использовать один и тот же action. Этот экшн при сохранении будет возвращать только id загруженного файла.
Добавим миграцию и создадим для нее модель через gii
Изменим action, для этого вынесем его в отдельный файл (необходимо скопировать экшн trntv\filekit\actions\UploadAction из папки vendor и внести правки в функцию run):
Теперь в ответе $output будет содержаться id загруженного файла.
В контроллере указываем action:
В файле \_form.php изменим события:
Из недостатков двух последний методов - файл будет загружаться даже если не сохранять саму модель, поскольку action выполняется при обращении. В качестве решения возможно использование cron для автоочистки неиспользуемых файлов.
Читайте также: