用Symfony3文件上传不起作用 [英] File upload with Symfony3 not working

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

问题描述

我试图用Symfony3上传文件,但没有运气。我有一个配置文件实体链接到用户实体与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( (
required=> false,
))
- > add(picture,FileType :: class,array(
required=> false,
));



类ProfileModel
{
private $ name;
private $ email;
私人$城市;
私人$国家;
private $ picture;

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

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

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

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


解决方案

Hewwo rashidkhan〜



Symfony文档在上传过程上相当完整,您是否阅读过这个文档?
http://symfony.com/doc/current/controller/upload_file.html



经过一些修改,我选择使用它作为服务。
下面是这个过程:

$ p $ app / config / config.yml $ b $ 参数


$ b

$ b

 参数:
语言环境:en
profile_directory:'%kernel.root_dir%/ .. / web / upload / profile'
another_directory :<%kernel.root_dir%/ .. / web / upload / another'

在<$ c



$ tw
debug:%kernel.debug%
strict_variables:%kernel.debug%
globals:
profile_directory:'/ upload / profile /'
another_directory:'/ upload / another /'

现在添加的两个 profile_directory 将被用作变量你的上传服务和分支指向targer目录。
我加了 another_directory 来解释一些事情。

2)创建在 src / YourBundle / Services / FileUploader.php 下创建一个新文件。 >
从这里开始,我的代码与Symfony网站上的代码有点不同。


$ b $ p $ File $> code $>

$ $ p $ <?php

命名空间YourBundle \Services;

使用YourBundle \Entity\ProfileModel;
使用YourBundle \Entity\Another;

class FileUploader {
private $ profileDir;
private $ anotherDir;

public function __construct($ profileDir){
$ this-> profileDir = $ profileDir;
$ this-> anotherDir = $ anotherDir;

$ b $ public function upload($ class){
if($ class instanceof ProfileModel){
$ file = $ class-> getPicture();
$ fileName ='picture - '。uniqid()。'。'。$ file-> guessExtension();
$ file-> move($ this-> profileDir,$ fileName);
$ class-> setPicture($ fileName);

$ b $ if($ class instanceof Another){
$ file = $ class-> getPicture();
$ fileName ='picture - '。uniqid()。'。'。$ file-> guessExtension();
$ file-> move($ this-> anotherDir,$ fileName);
$ class-> setPicture($ fileName);
}

return $ class;


$ c


<3>将服务注册到<$在服务 app / config / services.yml


$ b

 服务:
app.file_uploader:
class:YourBundle \Services\ FileUploader
参数:
- '%profile_directory%'
- '%another_directory%'

每个参数必须与 FileUploader.php 文件中的 private 顺序相同。
这些参数是我们在 app / config / config.yml 下<参数
中设置的参数。 4)编辑你的控制器:


控制器部分非常简单。 p>

在导入部分添加使用Symfony \ Component \HttpFoundation\File\File;


$ b $ newAction

  public function newAction(Request $ request)
{
$ profileModel = new ProfileModel();
$ form = $ this-> createForm('YourBundle\Form\ProfileModelType',$ profileModel);
$ form-> handleRequest($ request);
$ b $ if($ form-> isSubmitted()& $ amp; $ form-> isValid()){
//我们用这一行上传文件
$ profileModel = $这个 - >获得( 'app.file_uploader') - >上传($ profileModel);
$ em = $ this-> getDoctrine() - > getManager();
$ em-> persist($ profileModel);
$ em-> flush();

return $ this-> redirectToRoute('profile_model_show',array('id'=> $ profileModel-> getId()));

$ b $ return $ this-> render('YourBundle:Default:new.html.twig',array(
'profileModel'=> $ profileModel,
'form'=> $ form-> createView(),
));

editAction

  public function editAction($ request $ $ $ 
$ b $ //代码中的所有其他内容。
$ profileModel-> setPicture(new File($ this-> getParameter('profile_directory')。'/'。$ profileModel-> getPicture()));
[...]
}

我还没走得更远,所以我只能解释什么后修改...
在您的 editAction ,你也将不得不检查$ _FILES不是空的。
如果不是的话,那么你要做上传过程。
如果是这样的话,请确保不要编辑SQL查询中的图片列(您将必须执行自定义查询)



5)您的小枝视图


$ b $ < show.html.twig code

$ p

$ p $ < tr>
< th>图片< / th>
< td> {{profileModel.picture)}}< / td>
< / tr>

 < TR> 
< th>图片< / th>
< td>< img src ={{asset(profile_directory_profileModel.picture)}}>< / td>
< / tr>

index.html.twig
您可以添加(不替换)到 edit.html.twig 来预览实际的图片。



6)解释:
$ b app / config / config.yml 我们在文件中添加了一些用作参数的目录。

如果需要的话,稍后可以更容易地更改这些目录。 (不需要编辑大量文件... YAY!)

Twig目录总是从 / web 文件夹开始。



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



与Symfony网站的例子,我们将整个对象传递给上传服务。
然后,我们检查这个对象是从哪个类创建的,然后执行我们的上传过程。



然后控制器中的上传过程被缩短为单线。

在twig中,我们还将使用在 app / config / config.yml 取消小枝属性。
如上所述,如果我们的上传目录改变了,那么我们只需要编辑 app / config / config.yml 文件。





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


亲切地说,

Preciel。

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~

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) Add a few parameters to app/config/config.yml:

under parameters:

parameters:
    locale: en
    profile_directory: '%kernel.root_dir%/../web/upload/profile'
    another_directory: '%kernel.root_dir%/../web/upload/another'

under twig

twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
globals:
    profile_directory: '/upload/profile/'
    another_directory: '/upload/another/'

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) Create the service:

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 content:

<?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) Register the service to app/config/services.yml:

under services:

services:
    app.file_uploader:
    class: YourBundle\Services\FileUploader
    arguments:
        - '%profile_directory%'
        - '%another_directory%'

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) Edit your controller:

The controller part is quite simple.

Add use Symfony\Component\HttpFoundation\File\File; in the import section

Under 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(),
    ));
}

Under 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()));
    [...]
}

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) Your twig views:

Under show.html.twig

Change

<tr>
    <th>Picture</th>
    <td>{{ profileModel.picture) }}</td>
</tr>

to

<tr>
    <th>Picture</th>
    <td><img src="{{ asset(profile_directory~profileModel.picture) }}"></td>
</tr>

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) Explanations:

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.

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

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.

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天全站免登陆