Campos FileType en Symfony

Para subir archivos en Symfony se emplea campo FileType del componente Form

Contenido modificable

Si ves errores o quieres modificar/añadir contenidos, puedes crear un pull request. Gracias

Para el manejo de la subida de archivos se emplea el campo de formulario FileType, que representa un campo input file. Este campo se compone de las siguientes especificaciones:

Opciones

multiple

Type: boolean. Default: false

Si se establece en true, el usuario podrá subir múltiples archivos a la vez.

Opciones sobreescritas

compound

Type: boolean. Default: false

Esta opción especifica si el type contiene child types o no. Esta opción se maneja internamente para types incorporados, por lo que no hay necesidad de configurarla explícitamente.

data_class

Type: string. Default: File

Esta opción establece el mapeador de datos apropiado para archivos a usar por el type.

empty_data

Type: mixed. Default: null

Esta opción determina que valor devolverá el campo cuando el valor enviado esté vacío.

Opciones heredadas

Estas opciones se heredan de FormType: disabled, error_bubbling, error_mapping, label, label_attr.

Ejemplo de subida de archivo en Symfony

Suponemos que tenemos una clase User donde el usuario puede subir su currículum en pdf. La definición de UserType es:

// src/AppBundle/Form/UserType.php

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, array('label' => 'Nombre'))
            ->add('curriculum', FileType::class, array('label' => 'Currículum (PDF file)'))
            ->add('save', SubmitType::class, array('label' => 'Crear curriculum'))
        ;
    }

Cuando el formulario se envía, el campo curriculum será una instancia de UploadedFile. Puede usarse para mover el archivo curriculum a un directorio:

public function uploadAction()
{
    // ...

    if ($form->isValid()) {
        $someNewFilename = ...

        $form['attachment']->getData()->move($dir, $someNewFilename);

        // ...
    }

    // ...
}

El método move() recibe un directorio y un nombre de archivo como argumentos. Puedes generar el nombre del archivo así:

// utilizamos el nombre original del archivo
$file->move($dir, $file->getClientOriginalName());

// obtener un nombre aleatorio e intentar adivinar la extensión (es más seguro)
$extension = $file->guessExtension();
if (!$extension) {
    // la extensión no se ha podido adivinar
    $extension = 'bin';
}
$file->move($dir, rand(1, 99999).'.'.$extension);

Utilizar el nombre original con getClientOriginalName() no es seguro y puede manipularse por el usuario. Además, pueden contener caracteres que no están permitidos en nombres de archivos. Se debe sanitizar el nombre antes de usarlo directamente.

Una forma de hacer esto y más de forma automática es empleando Doctrine para la subida de archivos.