I have a form with a file upload field (limited to PDF format only). After the form has been submitted and a valid uploaded file is present, I rename and move the file. Then I try to display the page with the form again - at which point the Symfony\Component\HttpFoundation\File\File
class constructor throws a FileNotFoundException
because, for some reason, it's been handed the path to the no-longer-existing temp file.
Relevant facts:
- The form fields (including the file upload field) are not mapped to an entity because I'm using a Wordpress-style "meta" table for the additional data associated with the entity; the controller handles creating any new objects to be persisted.
- The new filename is successfully saved to the database; I've further verified that the error occurs with the $form->createView() call.
- Before anyone suggests that this was due to my PHP settings, note that I purposefully tried uploading a PDF file with a size below the limit.
- My temporary solution is to redirect to another page (there is no error when I do this), but longterm it's much more ideal to still show the form page after submitting the form.
- I tried overwriting the
UploadedFile
object I got from the form with theFile
object returned by the->move()
method, but this didn't help. - I also tried creating a child class of the built-in
FileType
class and changing thedata_class
to beSplFileInfo
(the parent class of Symfony'sFile
class) b/cSplFileInfo
doesn't throw an exception over an invalid path, but this had no effect either.
My interpretetation of what's happening is that, for some reason, when you create a form view Symfony instantiates a new File
object for the file upload field using the old, temporary file path - thus resulting in a fatal error that absolutely shouldn't be happening (because when would you ever not be moving the uploaded file?).
Any suggestions for things to try that I haven't thought of yet would be much appreciated!
Solved
I figured out the problem by looking at the stack trace - I have a Twig extension that was calling Request::createFromGlobals()
, and THAT resulted in trying to create a new UploadedFile object with the no-longer-existing temp file path. Having the extension get the already-existing Request
object in its constructor should prevent this.