问题
My question(s):
Does Symfony 2 have support for
PATCH
requests, or any type of partial form content submissions? If so, is there a "correct" (or, more accurately "preferred") way to do this?Aside from the
PRE_BIND
(see below) event approach, are there any other patterns or ways to solve this problem? If there are other ways of solving this problem, are any of them considered better, or worse, than others?
What I've found/done so far: According to a pull request on Github (#5576), work was done to support partial form bindings in Symfony 2 (from my understanding, targeting Symfony 2.2). However, I can't find any documentation or examples outside of that pull request that indicate how to use partial form bindings.
One solution that I've found may suit my purposes. The approach is to attach an event subscriber to the PRE_BIND
event for a form type, a cursory search of stackoverflow yielded the following answer which is similar to one I'm currently employing: https://stackoverflow.com/a/11687863/657674.
回答1:
For PATCH
requests, Symfony 2.3 (maybe earlier?) natively supports partial model updates. See explanation below.
For non-PATCH
requests (e.g. PUT
and POST
), you can still perform partial data binding by either creating and registering an event subscriber to manipulate the unsubmitted data to their original values, or you can write a custom request handler to always call the $form->submit()
method with $clearMissing
set to false
.
Handling Partial Binding with PATCH
Requests
After digging into the internals of Symfony a little bit more, and coming to a better understanding of event subscribers and form extensions, I stumbled upon the HttpFoundationRequestHandler
class. Basically, as of Symfony 2.3, instead of calling $form->submit($request)
when binding a form's submitted data developers should be calling $form->handleRequest($request)
; this invokes the attached request handler (by default HttpFoundationRequestHandler
). The request handler does a few things, but most importantly is how it calls $form->submit()
. It passes a value of false
into the form's submit
method if the request method was PATCH
telling the form not to bind unsupplied form data as null
values.
There are some caveats around using the PATCH
method in Symfony 2.3 that can be further explained by Symfony's documentation:
How to use HTTP Methods beyond GET and POST in Routes:
"Unfortunately, life isn't quite this simple, since most browsers do not support sending PUT and DELETE requests. Fortunately Symfony2 provides you with a simple way of working around this limitation. By including a _method parameter in the query string or parameters of an HTTP request, Symfony2 will use this as the method when matching routes."
The above quote from Symfony's documentation explains that most browsers do not support sending PUT
, PATCH
, or DELETE
requests. Which is a problem because for us to leverage Symfony's native support for partial form updates, we need to use a PATCH
request. However, Symfony provides an answer to this. The documentation tells us that we can use the _method
parameter or form value to spoof the actual request we want and Symfony will know exactly what we mean. For _method
to be understood though, you may have to enable the http_method_override
configuration option, e.g.:
# config.yml
framework:
http_method_override: true
...
There are also other ways of telling Symfony what method the form should use, and those can be found here: Changing the Action and Method of a Form.
来源:https://stackoverflow.com/questions/19793767/does-symfony-2-support-partial-form-binding