Documentação do Symfony - versão 3.1
Renderizada do repositório symfony-docs-pt-BR no Github
Note
Em vez de você mesmo lidar com o upload de arquivos, considere o uso do bundle VichUploaderBundle criado pela comunidade. Esse bundle fornece todas as operações comuns (como renomear, salvar e excluir arquivos) e é bem integrado com o ORM Doctrine, ODM MongoDB, ODM PHPCR e Propel.
Imagine que você tem uma entidade Product
em sua aplicação e você quer
adicionar um catálogo PDF para cada produto. Para fazer isso, adicione uma nova propriedade
chamada `` brochure`` na entidade Product
:
// src/AppBundle/Entity/Product.php
namespace AppBundle\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;
}
}
Note que o tipo da coluna brochure
é string
em vez de binary
ou blob
porque ela só armazena o nome do arquivo PDF em vez do conteúdo do arquivo.
Em seguida, adicione um novo campo brochure
ao formulário que gerencia a entidade Product
:
// src/AppBundle/Form/ProductType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('brochure', FileType::class, array('label' => 'Brochure (PDF file)'))
// ...
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Product',
));
}
public function getName()
{
return 'product';
}
}
Agora, atualize o template que processa o formulário para exibir o novo campo brochure
(o código exato do template para adicionar depende do método usado pela sua aplicação
para personalizar a renderização do formulário):
1 2 3 4 5 6 7 8 | {# app/Resources/views/product/new.html.twig #}
<h1>Adding a new product</h1>
{{ form_start() }}
{# ... #}
{{ form_row(form.brochure) }}
{{ form_end() }}
|
Finalmente, você precisa atualizar o código do controlador que manipula o formulário:
// src/AppBundle/Controller/ProductController.php
namespace AppBundle\ProductController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Product;
use AppBundle\Form\ProductType;
class ProductController extends Controller
{
/**
* @Route("/product/new", name="app_product_new")
*/
public function newAction(Request $request)
{
$product = new Product();
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);
if ($form->isValid()) {
// $file stores the uploaded PDF file
/** @var Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $product->getBrochure();
// Generate a unique name for the file before saving it
$fileName = md5(uniqid()).'.'.$file->guessExtension();
// Move the file to the directory where brochures are stored
$brochuresDir = $this->container->getParameter('kernel.root_dir').'/../web/uploads/brochures';
$file->move($brochuresDir, $fileName);
// Update 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', array(
'form' => $form->createView(),
));
}
}
Existem algumas coisas importantes a considerar no código do controlador acima:
brochure
contém todo o conteúdo
do arquivo PDF. Uma vez que esta propriedade armazena apenas o nome do arquivo, você deve definir
seu novo valor antes persistir as alterações da entidade;UploadedFile
, que
fornece métodos para as operações mais comuns ao lidar com o upload de arquivos;Uploaded
fornece métodos para obter a extensão de arquivo original
(getExtension()
),
o tamanho do arquivo original (getClientSize()
)
e o nome do arquivo original (getClientOriginalName()
).
No entanto, eles são considerados não seguros porque um usuário mal-intencionado poderia adulterar
essas informações. Por isso é sempre melhor gerar um nome único e
usar o método guessExtension()
para deixar o Symfony escolher a extensão correta de acordo com o tipo MIME do arquivo;UploadedFile
também fornece um método move()
para armazenar o arquivo no diretório pretendido. Definir o caminho deste diretório
como uma opção de configuração da aplicação é considerado uma boa prática que
simplifica o código: $this->container->getParameter('brochures_dir')
.Agora você pode usar o código a seguir para conectar-se a brochura PDF de um produto:
1 | <a href="{{ asset('uploads/brochures/' ~ product.brochure) }}">View brochure (PDF)</a>
|