我有一个Symfony2应用程序,其中包含一个文件类型字段的表单。我需要在那里上传一个学生的图像,所以我帮助了这个文档:How to Upload Files
这是我的代码:
控制器:
Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
实体:
public function createAction(Request $request)
{
if ($request->isXmlHttpRequest() && !$request->isMethod('POST')) {
throw new HttpException('XMLHttpRequests/AJAX calls must be POSTed');
}
$entity = new Student();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$file = $entity->getPhoto();
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$photoDir = $this->container->getParameter('kernel.root_dir').'/../web/uploads/images';
$file->move($photoDir, $fileName);
$entity->setPhoto($fileName);
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
if ($request->isXmlHttpRequest()) {
return new JsonResponse(array('message' => 'Success!','success' => true), 200);
}
if ($request->isMethod('POST')) {
return new JsonResponse(array('message' => 'Invalid form','success' => false), 400);
}
return $this->redirect($this->generateUrl('student_show', array('id' => $entity->getId())));
}
return $this->render('BackendBundle:Student:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
formtype:
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
//...
/**
* @var string
*
* @ORM\Column(name="photo", type="string", length=255, nullable=true)
*
*/
private $photo;
public function setPhoto($photo)
{
$this->photo = $photo;
return $this;
}
public function getPhoto()
{
return $this->photo;
}
使用Javascript:
//...
->add('photo', 'file', array('required' => false))
//...
我现在遇到的问题是我必须使用Ajax请求,但不知道如何发送该文件字段,然后可以在Symfony控制器中使用它。
我见过一些 //...
$('.form_student').on("submit",function(event) {
event.preventDefault();
$.ajax({
type: 'POST',
url: Routing.generate('student_create'),
data: $(this).serialize(),
dataType: 'json',
success: function(response) {
alert(response.message);
},
error: function (response, desc, err){
if (response.responseJSON && response.responseJSON.message) {
alert(response.responseJSON.message);
}
else{
alert(desc);
}
}
});
});
,但不知道它是如何使用的。
你能帮帮我吗?
答案 0 :(得分:11)
我已经解决了我的代码更改问题:
data: new FormData($(this)[0])
代替data: $ (this).serialize()
添加ajax请求:
processData: false,
contentType: false,
cache: false,
并正确发送文件
答案 1 :(得分:3)
如果您想使用Ajax,我可以通过以下方式解决此问题。
在您的实体中声明:
/**
*@ORM\HasLifecycleCallbacks
*/
class Student
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
/**
* @Assert\File(
* maxSize="60000",
* )
*/
private $file;
private $temp;
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
if (isset($this->path)) {
// store the old name to delete after the update
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
return $this->file;
}
public function getAbsolutePath()
{
return null === $this->path
? null
: $this->getUploadRootDirPath().'/'.$this->path;
}
public function getWebPath()
{
return null === $this->path
? null
: $this->getUploadDirPath().'/'.$this->path;
}
protected function getUploadRootDirPath()
{
// the absolute directory path where uploaded
// documents should be saved
return __DIR__.'/../../../../web/'.$this->getUploadDirPath();
}
protected function getUploadDirPath()
{
// get rid of the __DIR__ so it doesn't screw up
// when displaying uploaded doc/image in the view.
return 'uploads/student_photos';
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile()) {
// do whatever you want to generate a unique name
$filename = basename($this->getFile()->getClientOriginalName(),'.'.$this->getFile()->getClientOriginalExtension());
$this->path = $filename.'.'.$this->getFile()->getClientOriginalExtension();
if(file_exists($this->getUploadRootDirPath().'/'.$this->path)==1)
{
$date = date('-d_M_Y_H:i');
$this->path = $filename.$date.'.'.$this->getFile()->getClientOriginalExtension();
}
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
$this->getFile()->move($this->getUploadRootDirPath(), $this->path);
if (isset($this->temp)) {
// delete the old image
unlink($this->getUploadRootDirPath().'/'.$this->temp);
// clear the temp image path
$this->temp = null;
}
$this->file = null;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
$file = $this->getAbsolutePath();
if ($file) {
unlink($file);
}
}
}
在您的FormType中:
->add('file', null, array('label' => 'Profile Picture', 'required' => false))
在你的控制器中:
$entity->setFile($request->files->get('photo')); //here you have get your file field name
$em->persist($entity);
$em->flush();
你的ajax看起来很好,但如果这不会比使用
data:new FormData(this),
而不是
data: $(this).serialize(),
并在ajax中添加这两个参数:
processData: false,
contentType: false
您可以根据需要更改保存文件方法,并将路径字段更改为照片。
答案 2 :(得分:0)
更新
我认为问题在于,如果您通过ajax提交,则必须对控制器中收到的信息进行反序列化
相应地,您应该明确地序列化表单,而不是使用此a = b += 12; // works in C#, but not in VB
echo "My Page" > index.html