As you might remember, the filters and validators attached to a form model are typically
stored in an InputFilter
container which consists of inputs (an input is typically represented
by the Input
class belonging to the Zend\InputFilter
namespace). For usual form fields, the filters
are executed before validators, and validators are executed after filters.
However, for file uploads, there are some important differences:
FileInput
should be utilized instead of the Input
class;For storing validation rules for uploaded files, you must use the FileInput
class instead of the
usual Input
class.
In your form model's addInputFilter()
private method, you add the validation rules for the
file input as follows:
$inputFilter->add([
'type' => 'Zend\InputFilter\FileInput',
'name' => 'file', // Element's name.
'required' => true, // Whether the field is required.
'filters' => [ // Filters.
// Put filter info here.
],
'validators' => [ // Validators.
// Put validator info here.
]
]);
Above, we set the "type" key (line 2) with the value Zend\InputFilter\FileInput
class name. The
rest of keys is analogous to those we used before when adding validation rules for a form model.
The behaviour of FileInput
class differs from the Input
in the following aspects:
It expects the data you pass as input to be in the $_FILES
array format (an array entry with
tmp_name
, error
, type
keys).
A Zend\Validator\File\Upload
validator is automatically inserted before all other validators
into the validator chain of the input.
The validators inserted to the validator chain of the input are executed before the
filters inserted into its filter chain. This is opposite to the behaviour of the Input
class.
For usual form fields, the filters are typically executed before validators, and validators are executed after filters. However, for file uploads, this sequence is opposite.
For file uploads, validators are executed before filters. This behaviour is inverse to the usual behaviour.
When working with uploaded files, we first need to check that data extracted from $_FILES
super-global array is correct, and then do anything else with the files (moving the file into a
storage directory, renaming it, etc.) Because of that, file validators need to be run first turn, and
filters to be executed last.
To see how this is performed, recall the typical workflow for a form:
setData()
method to fill in the form with data.isValid()
method to execute filters and validators in the input filter attached to form.getData()
to extract the filtered and validated data from
the input filter attached to form.getMessages()
to retrieve the validation error messages.When using a FileInput
input, the workflow is the same, however it is important to understand what
happens on each of its steps:
setData()
method to fill in the form with data.isValid()
method to execute validators in the input filter attached to form.getData()
to execute filters and extract the filtered
and validated data from the input filter attached to form.getMessages()
to retrieve the validation error messages.Please note that for
FileInput
input, the attached filters are only run if thegetData()
method is called.
When you use both Input
and FileInput
inputs in your form's input filter (which is a common case),
the filters are still executed first for usual inputs, but validators are executed first for file inputs.