使用Symfony3上传文件无效

时间:2016-08-14 13:35:20

标签: php forms file-upload image-uploading symfony

我正在尝试使用Symfony3上传文件,但没有运气。我有一个Profile实体,它链接到具有1-1关系的User实体。配置文件包含图片列。 我创建了一个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;

在Controller中我正在创建这样的表单。

$profileForm = $this->createForm(ProfileType::class, $profileModel);

当我得到图片时,它只包含名称。

$file = $profileForm->get("picture")->getData();

3 个答案:

答案 0 :(得分:3)

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'
<{1>}

下的

twig

刚刚添加的两个twig: debug: "%kernel.debug%" strict_variables: "%kernel.debug%" globals: profile_directory: '/upload/profile/' another_directory: '/upload/another/' 将用作上传服务和twig中的变量,以指向targer目录。 我添加了profile_directory来解释更多内容。

2)创建服务:

another_directory下创建一个新文件 从这里开始,我的代码与您在Symfony网站上找到的代码略有不同。

src/YourBundle/Services/FileUploader.php内容:

FileUploader.php

3)将服务注册到<?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; } }

app/config/services.yml下的

services

每个参数的顺序必须与services: app.file_uploader: class: YourBundle\Services\FileUploader arguments: - '%profile_directory%' - '%another_directory%' 文件中private的顺序相同。 这些论点是我们在FileUploader.php app/config/config.ymlparameters中设置的论点。

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是否为空。 如果不是,则执行上传过程。 如果是,请确保不编辑SQL查询中的picture列(您必须执行自定义查询)

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网站示例不同,我们将整个对象传递给上传服务。 然后,我们检查这个对象是从哪个类创建的,并根据它来完成上传过程。

然后,您在控制器中的上传过程将缩短为一行。

在twig中,我们还将使用app/config/config.yml中设置的目录变量取消twig属性。 如上所述,如果我们的上传目录发生变化,我们就必须编辑app/config/config.yml文件。


我希望这可以帮助您解决上传问题。

亲切,
Preciel。

答案 1 :(得分:0)

你应该试试

$form = $this->createForm(ProfileType::class, $profileModel); $form->handleRequest($request); $file = $profileModel->getBrochure();

更多:http://symfony.com/doc/current/controller/upload_file.html

答案 2 :(得分:0)

如果您要在Symfony中上载任何类型的文件,那么我有一个非常简单的解决方案,下面将对此进行介绍。为什么我要提供简单的解决方案,因为每当有新版本出现时,您都必须在services.yaml中进行一些设置,或者除了主控制器之外还必须创建其他文件。

解决方案是:只需在主控制器中使用 move($ storing_place,$ actual_filename)函数。

在控制器文件中放置以下代码。

$folder_path = 'public/uploads/brochures/';
$file = $request->files->get('myfile');
$fileName = $request->files->get('myfile')->getClientOriginalName();
$file->move($folder_path, $fileName);        
return new Response($file);

希望给出的解决方案将对您的项目有所帮助。