Я пытаюсь загрузить файл с Symfony3, но не повезло. У меня есть объект профиля, который связан с объектом User с отношением 1-1. Профиль содержит столбец изображения. Я создал ProfileType и Profile Model. При отправке формы модель содержит только имя файла и ничего больше. Массив $ _FILES также пуст. Это код.
$builder ->add("name", TextType::class, array( "required" => true, )) ->add("email", EmailType::class, array( "required" => true, )) ->add("city", TextType::class, array( "required" => false, )) ->add("country", ChoiceType::class, array( "required" => false, )) ->add("picture", FileType::class, array( "required" => false, )); class ProfileModel { private $name; private $email; private $city; private $country; private $picture;
В контроллере я создаю такую форму.
$profileForm = $this->createForm(ProfileType::class, $profileModel);
Когда я получаю изображение, он содержит только имя.
$file = $profileForm->get("picture")->getData();
Hewwo rashidkhan ~
Symfony doc полностью завершен в процессе загрузки, вы его прочитали?
http://symfony.com/doc/current/controller/upload_file.html
После нескольких изменений я решил использовать его в качестве сервиса. Вот этот процесс:
1) Добавьте несколько параметров в app/config/config.yml
:
по parameters
:
parameters: locale: en profile_directory: '%kernel.root_dir%/../web/upload/profile' another_directory: '%kernel.root_dir%/../web/upload/another'
под twig
twig: debug: "%kernel.debug%" strict_variables: "%kernel.debug%" globals: profile_directory: '/upload/profile/' another_directory: '/upload/another/'
Два добавленных ранее файла profile_directory будут использоваться в качестве переменных как в вашей службе загрузки, так и в twig, чтобы указать каталог-указатель. Я добавил another_directory
чтобы немного объяснить немного позже.
2) Создайте сервис:
Создайте новый файл под src/YourBundle/Services/FileUploader.php
Отсюда мой код немного отличается от того, что вы можете найти на сайте Symfony.
FileUploader.php
:
<?php namespace YourBundle\Services; use YourBundle\Entity\ProfileModel; use YourBundle\Entity\Another; class FileUploader { private $profileDir; private $anotherDir; public function __construct($profileDir) { $this->profileDir=$profileDir; $this->anotherDir=$anotherDir; } public function upload($class) { if($class instanceof ProfileModel) { $file=$class->getPicture(); $fileName='picture-'.uniqid().'.'.$file->guessExtension(); $file->move($this->profileDir, $fileName); $class->setPicture($fileName); } if($class instanceof Another) { $file=$class->getPicture(); $fileName='picture-'.uniqid().'.'.$file->guessExtension(); $file->move($this->anotherDir, $fileName); $class->setPicture($fileName); } return $class; } }
3) Зарегистрируйте службу в app/config/services.yml
:
по services
:
services: app.file_uploader: class: YourBundle\Services\FileUploader arguments: - '%profile_directory%' - '%another_directory%'
Каждый аргумент должен быть в том же порядке, что и ваш private
файл FileUploader.php
. Этими аргументами являются те, которые мы установили в app/config/config.yml
в parameters
.
4) Отредактируйте свой контроллер:
Часть контроллера довольно проста.
Добавьте use Symfony\Component\HttpFoundation\File\File;
в разделе импорта
В разделе newAction
public function newAction(Request $request) { $profileModel = new ProfileModel(); $form = $this->createForm('YourBundle\Form\ProfileModelType', $profileModel); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // We upload the file with this line $profileModel=$this->get('app.file_uploader')->upload($profileModel); $em = $this->getDoctrine()->getManager(); $em->persist($profileModel); $em->flush(); return $this->redirectToRoute('profile_model_show', array('id' => $profileModel->getId())); } return $this->render('YourBundle:Default:new.html.twig', array( 'profileModel' => $profileModel, 'form' => $form->createView(), )); }
В разделе editAction
public function editAction(Request $request, ProfileModel $profileModel) { // Add this live above everything else in the code. $profileModel->setPicture(new File($this->getParameter('profile_directory').'/'.$profileModel->getPicture())); [...] }
Я не зашел слишком далеко, поэтому я могу только объяснить, что изменить после … В вашем editAction
вам также нужно будет проверить, что $ _FILES не пуст. Если это не так, то вы выполняете процесс загрузки. Если это так, убедитесь, что вы не отредактировали столбец picture
в SQL-запросе (вам нужно будет выполнить пользовательский запрос)
5) Ваши взгляды на ветку:
Под show.html.twig
+ Изменить
<tr> <th>Picture</th> <td>{{ profileModel.picture) }}</td> </tr>
в
<tr> <th>Picture</th> <td><img src="{{ asset(profile_directory~profileModel.picture) }}"></td> </tr>
То же самое касается index.html.twig
. И вы можете добавить (не заменять) его на edit.html.twig
чтобы получить предварительный просмотр фактического изображения.
6) Пояснения:
В app/config/config.yml
мы добавили несколько каталогов для использования в качестве параметров в ваших файлах.
Впоследствии это облегчит изменение этих каталогов, если это необходимо. (Не нужно будет редактировать тонны файлов … YAY!)
Каталоги Twig всегда начинаются с папки /web
.
Эти каталоги используются, когда мы регистрируем нашу службу в качестве arguments
. Они установят нашу переменную в файле службы FileUploader.php
.
В отличие от сайта Symfony, мы передаем весь объект службе загрузки. Затем мы проверяем, из какого класса был создан этот объект, и выполняем в нем наш процесс загрузки.
Затем процесс загрузки в контроллере сокращается до одной строки.
В ветке мы также будем использовать переменную каталога, установленную в app/config/config.yml
чтобы установить свойство twig
. Как сказано выше, если наш каталог загрузки изменится, нам просто нужно будет отредактировать файл app/config/config.yml
.
Надеюсь, это поможет вам решить проблемы с загрузкой.
Сердечно,
Preciel.
Ты должен попытаться
$form = $this->createForm(ProfileType::class, $profileModel); $form->handleRequest($request); $file = $profileModel->getBrochure();
Подробнее: http://symfony.com/doc/current/controller/upload_file.html