symfony上传图片示例代码测试不成功的原因

想起之前按着symfony文档测试上传文件的示例上传没有成功,在此仅记录下以避免再次踩坑

实体添加文件字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// src/Entity/Product.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

class Product
{
// ...

/**
* @ORM\Column(type="string")
*
* @Assert\NotBlank(message="Please, upload the product brochure as a PDF file.")
* @Assert\File(mimeTypes={ "application/pdf" })
*/
private $brochure;

public function getBrochure()
{
return $this->brochure;
}

public function setBrochure($brochure)
{
$this->brochure = $brochure;

return $this;
}
}

formType添加相应字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// src/Form/ProductType.php
namespace App\Form;

use App\Entity\Product;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('brochure', FileType::class, ['label' => 'Brochure (PDF file)'])
// ...
;
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Product::class,
]);
}
}

控制器提交代码

此处将$file = $product->getBrochure();(标记1) 更改为 $file = $form->get('brochure')->getData();(标记2)。
因为 orm获取的brochure是对应该字段的类型 字符串
而 form->get()->getData获取的才是实际的UploadedFile对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// src/Controller/ProductController.php
namespace App\Controller;

use App\Entity\Product;
use App\Form\ProductType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class ProductController extends AbstractController
{
/**
* @Route("/product/new", name="app_product_new")
*/
public function new(Request $request)
{
$product = new Product();
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
// $file stores the uploaded PDF file
/** @var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $product->getBrochure();

$fileName = $this->generateUniqueFileName().'.'.$file->guessExtension();

// Move the file to the directory where brochures are stored
try {
$file->move(
$this->getParameter('brochures_directory'),
$fileName
);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}

// updates the 'brochure' property to store the PDF file name
// instead of its contents
$product->setBrochure($fileName);

// ... persist the $product variable or any other work

return $this->redirect($this->generateUrl('app_product_list'));
}

return $this->render('product/new.html.twig', [
'form' => $form->createView(),
]);
}

/**
* @return string
*/
private function generateUniqueFileName()
{
// md5() reduces the similarity of the file names generated by
// uniqid(), which is based on timestamps
return md5(uniqid());
}
}
分享