Symfony3 无法上传文件 [英] File upload with Symfony3 not working
问题描述
我正在尝试使用 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_directory
added 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 private
in 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 twig
property.
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屋!