Symfony3 无法上传文件 [英] File upload with Symfony3 not working

查看:27
本文介绍了Symfony3 无法上传文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Symfony3 上传文件,但没有成功.我有一个 Profile 实体,它以 1-1 的关系链接到 User 实体.配置文件包含一个图片列.我创建了 ProfileType 和 Profile Model.提交表单后,模型仅包含文件名,不包含其他任何内容.$_FILES 数组也是空的.这是代码.

I am trying to upload file with Symfony3 but with no luck. I have a Profile entity which is linked to User entity with 1-1 relationship. The profile contains a picture column. I have created a ProfileType and Profile Model. Upon submitting the form, the model contains only the File name and nothing else. The $_FILES array is also empty. This is the code.

        $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;

在控制器中,我正在创建这样的表单.

In Controller I am creating the form like this.

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

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

When I get the picture, It contains just the name.

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

推荐答案

Hewwo Rashidkhan~

Hewwo rashidkhan~

Symfony 文档在上传过程中非常完整,您阅读了吗?
http://symfony.com/doc/current/controller/upload_file.html

Symfony doc is quite complete on the upload process, did you read it?
http://symfony.com/doc/current/controller/upload_file.html

经过几次修改后,我选择将其用作服务.流程如下:

After a few modifications, I choose to use it as service. Here is the process:

1)在app/config/config.yml中添加几个参数:

1) Add a few parameters to app/config/config.yml:

参数下:

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 来解释更多内容.

The two profile_directoryadded just now will be used as variables in both your upload service and twig to point the targer directory. I added another_directory to explain something more a bit after.

2) 创建服务:

src/YourBundle/Services/FileUploader.php下新建一个文件
从这里开始,我的代码与您在 Symfony 站点上找到的代码略有不同.

Create a new file under src/YourBundle/Services/FileUploader.php
From here, my code is a bit different than what you can find on the Symfony site.

FileUploader.php 内容:

<?php

namespace YourBundleServices;

use YourBundleEntityProfileModel;
use YourBundleEntityAnother;

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: YourBundleServicesFileUploader
    arguments:
        - '%profile_directory%'
        - '%another_directory%'

每个参数的顺序必须与 FileUploader.php 文件中的 private 相同.这些参数是我们在 parameters 下的 app/config/config.yml 中设置的参数.

Each argument must be in the same order as your privatein the FileUploader.php file. Those arguments are the ones we setted in app/config/config.yml under parameters.

4) 编辑您的控制器:

控制器部分非常简单.

在导入部分添加use SymfonyComponentHttpFoundationFileFile;

newAction

public function newAction(Request $request)
{
    $profileModel = new ProfileModel();
    $form = $this->createForm('YourBundleFormProfileModelType', $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 列(您必须进行自定义查询)

I haven't gone more far, so I can only explain what to modify after... In your editAction, you will also have to check that $_FILES isn't empty. If it's not, then you do the upload process. If it's, then make sure to not edit the picture column in the SQL query (you will have to do a custom query)

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 以预览实际图片.

Same goes for the index.html.twig. And you can add (not replace) it to the edit.html.twig to get a preview of the actual picture.

6) 说明:

app/config/config.yml 中,我们添加了一些目录作为文件中的参数.
如果需要,稍后可以更轻松地更改这些目录.(不必编辑大量文件......耶!)
Twig 目录总是从 /web 文件夹开始.

In app/config/config.yml we added a few directory to use as parameters in your files.
It will later make it easier to change those directories if needed. (Won't have to edit tons of files... YAY!)
Twig directories always start from the /web folder.

当我们将服务注册为 arguments 时会使用这些目录.他们将在服务文件 FileUploader.php 中设置我们的变量.

Those directory are used when we register our service as arguments. They will set our variable in the service file FileUploader.php.

与 Symfony 站点示例不同,我们将整个对象传递给上传服务.然后,我们检查这个对象是从哪个类创建的,并基于它执行我们的上传过程.

Unlike the Symfony site exemple, we pass the whole object to the upload service. We then, check from which class this object was created and do our upload process based in it.

您在控制器中的上传过程然后被缩短为一行.

Your upload process in the controller is then shortened to a single line.

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

In twig, we will also use the directory variable set in app/config/config.yml undet the twigproperty. Like said above, if our upload directory change, we will then just have to edit the app/config/config.yml file.


我希望这能帮助您解决上传问题.


I hope this will help you solve your upload issues.

诚挚的,
珍贵.

Cordially,
Preciel.

这篇关于Symfony3 无法上传文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆