Cómo diferenciar un input file vacío de uno sin cambios

1,763 views
Skip to first unread message

Gorka

unread,
Aug 25, 2008, 11:03:01 AM8/25/08
to symfony-es
Hola a todos,

Utilizando Symfony 1.1.1 con el framework de formularios, ¿es posible
distinguir un input file vacío de uno sin cambios?

Lo que quiero hacer:

Digamos que los post de un blog pueden tener un archivo opcional
adjunto. En la página de edición de post, si el post ya tenía un
archivo el campo file se deshabilita mediante javascript y se muestra
un botón 'eliminar'. Al pulsar este botón, y utilizando javascript, se
vacía el valor del campo file y se habilita, deshabilitando después el
botón eliminar. Este botón volverá a habilitarse cuando el campo file
cambie de valor.

En el lado del servidor, no veo cómo distinguir cuándo el campo file
no ha cambiado (estaba por tanto deshabilitado y no ha enviado ningún
valor al servidor) o cuándo ha sido vaciado (habilitado, por lo que ha
enviado un valor vacío). No estoy 100% seguro de que este sea un
comportamiento estándar para todos los navegadores, de modo que las
confirmaciones o las críticas son bienvenidas.

He probado a añadir un campo oculto, pero no me gusta la idea por dos
motivos: por un lado, modifica la lógica de subida de ficheros, y por
otro el framework de formularios se queja -con razón- de que hay un
campo adicional.

¿Cuál es la mejor forma de saber si un campo file ha sido vaciado o si
simplemente no ha cambiado?

pablodip

unread,
Aug 25, 2008, 11:22:15 AM8/25/08
to symfony-es
Que yo sepa los input file no tienen valor por defecto por seguridad,
por lo que es igual uno vacío que uno sin cambios.

Para lo que pretendes hacer otra posible solución es que cuando exista
la imagen si se envía otra se reemplaza, y luego para eliminarla si
existe se puede poner un checkbox, un link simple, un link ajax...

Saludos!

Gorka

unread,
Aug 25, 2008, 11:31:03 AM8/25/08
to symfony-es
Hola Pablo,

Como bien dices no tienen valor por defecto por cuestión de seguridad,
pero con el escenario que he descrito sí se comportan de forma
diferente: un campo file deshabilitado no envía nada al servidor. Un
campo file vacío, por contra, envía un file vacío con el código de
error correspondiente. Esta es la diferencia que quiero utilizar para
lo que propongo en el primer mensaje, la única duda que me cabe es si
es un comportamiento estándar para todos los navegadores y cómo
acceder a esta diferencia de forma limpia desde el framework de
formularios de symfony.

Gorka

unread,
Aug 25, 2008, 11:45:50 AM8/25/08
to symfony-es
Un ejemplo rápido de la diferencia entre uno y otro:

<html>
<head>
<title>Prueba</title>
</head>
<body>
<?php
print_r($_FILES);
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="archivo1" /><br />
<input type="file" name="archivo2" disabled="disabled" /><br />
<input type="submit" value="Test" />
</form>
</body>
</html>

Si lo pruebas, verás que archivo1 siempre se envía al servidor: con
contenido cuando eliges un fichero y vacío con código de error 4
cuando no seleccionas nada. Estos serían los casos en los que el
archivo se ha cambiado por otro o ha sido eliminado.

El campo archivo2, sin embargo, no envía nada al servidor al estar
deshabilitado. Este sería el caso en el que el campo no se ha cambiado
(no se ha pulsado el botón eliminar).

Un saludo!

On Aug 25, 5:22 pm, pablodip <pablo...@gmail.com> wrote:

pablodip

unread,
Aug 25, 2008, 12:19:35 PM8/25/08
to symfony-es
Vale, no sabía que había esa diferencia, pero acabo de probarlo y al
menos en firefox si lo hace, el tema es asegurarse de que es estandar
como dices.
La única pega que le veo es que para hacer ese comportamiento
necesitas obligatoriamente javascript, pero bueno, te digo cómo puedes
hacerlo.

Con sfValidatorFile como habrás comprobado le da igual si el archivo
no está o está mal, simplemente lo da como incorrecto.

Lo que puedes hacer es poner como no requerido el validador, y al
comprobar el formulario si es válido compruebas si existe el archivo
en $_FILES. Si existe está vacío y sino deshabilitado.

Esta es la manera rápida, la mejor para mi es hacer un validador que
extienda a sfValidatorFile y que detecte el error de que no hay
archivo, asi que como veas ;)

Saludos!

Gorka

unread,
Aug 25, 2008, 1:12:45 PM8/25/08
to symfony-es
Respecto a la dependencia de Javascript, este widget sólo se usa en el
backend donde se puede contar con que esté presente. Aunque no
estuviera presente, el campo pasaría a tener el comportamiento por
defecto del widget FormInputFile, lo que no debería ser un problema...
¿o sí? Pensando en esto y echando un vistazo al manual de formularios
me ha surgido una duda más importante:

El código del manual está preparado para que el campo fichero sea
obligatorio. Para que el formulario valide, cada vez que se edita un
elemento con un campo fichero es obligatorio seleccionar el fichero.
Es decir, cada vez que edite el post para cambiar el título tengo que
volver a seleccionar el archivo adjunto al ser este campo obligatorio,
de lo contrario el formulario no validará. Y, aunque hiciera el campo
opcional para pasar la validación, perdería el valor anterior al
guardar el formulario.

Estoy seguro de que estoy pasando algo por alto, con algo tan común
como la subida de ficheros tendría que haber un montón de hilos en el
foro de symfony con esta misma duda...

pablodip

unread,
Aug 26, 2008, 5:39:15 AM8/26/08
to symfony-es
> Respecto a la dependencia de Javascript, este widget sólo se usa en el
> backend donde se puede contar con que esté presente. Aunque no
> estuviera presente, el campo pasaría a tener el comportamiento por
> defecto del widget FormInputFile, lo que no debería ser un problema...
> ¿o sí? Pensando en esto y echando un vistazo al manual de formularios
> me ha surgido una duda más importante:

No he entendido todo lo que dices, pero creo que te estás haciendo un
lío :P

> El código del manual está preparado para que el campo fichero sea
> obligatorio. Para que el formulario valide, cada vez que se edita un
> elemento con un campo fichero es obligatorio seleccionar el fichero.
> Es decir, cada vez que edite el post para cambiar el título tengo que
> volver a seleccionar el archivo adjunto al ser este campo obligatorio,
> de lo contrario el formulario no validará. Y, aunque hiciera el campo
> opcional para pasar la validación, perdería el valor anterior al
> guardar el formulario.

No he visto el manual, pero el archivo puede ser opcional también, con
eso es con lo que tienes que jugar para ver los estados que quieres
ver del campo.

Si es para el backend para mi lo estás complicando demasiado a no ser
que lo que busques sea aprender. Sino con un checkbox para borrar el
archivo acabarías mucho antes ;)

Saludos!
Reply all
Reply to author
Forward
0 new messages