如何在SilverStripe中从HTTPRequest获取PUT和DELETE请求参数?
Great question! I’ve dealt with this exact scenario when building REST endpoints using the HTTPRequest class—frustrating that there’s no built-in putVars() or deleteVars() like there is for GET/POST, but there’s a clean way to replicate that convenience.
First, the core issue
PUT and DELETE request parameters are typically stored in the request body (either as a query string like key=value&foo=bar or JSON payload), which is exposed via the HTTPRequest->body property. Since the class doesn’t parse this automatically for non-GET/POST methods, we need to handle the parsing ourselves.
Option 1: Quick helper functions for query-string formatted bodies
If your PUT/DELETE requests send data in the standard application/x-www-form-urlencoded format (same as POST forms), you can use PHP’s parse_str() function to convert the body string into an associative array—just like how getVars() works:
function getPutVars(HTTPRequest $request) { $params = []; // Only parse if it's a PUT request if (strtoupper($request->method) === 'PUT') { parse_str($request->body, $params); } return $params; } function getDeleteVars(HTTPRequest $request) { $params = []; // Note: DELETE might also have params in the URL query string if (strtoupper($request->method) === 'DELETE') { // Parse body params first parse_str($request->body, $params); // Merge with URL query params if needed $params = array_merge($request->getVars(), $params); } return $params; }
Option 2: Handling JSON payloads (common in modern APIs)
If your requests send JSON data (Content-Type: application/json), use json_decode() instead:
function getJsonRequestBody(HTTPRequest $request) { $contentType = $request->getHeader('Content-Type'); if (strpos($contentType, 'application/json') === false) { return []; } $params = json_decode($request->body, true); return is_array($params) ? $params : []; }
Option 3: Extend HTTPRequest for true convenience
If you want a seamless experience like getVars() or postVars(), extend the HTTPRequest class to add your own methods:
class ExtendedHTTPRequest extends HTTPRequest { public function putVars() { $params = []; if (strtoupper($this->method) === 'PUT') { parse_str($this->body, $params); } return $params; } public function deleteVars() { $params = $this->getVars(); // Start with URL query params if (strtoupper($this->method) === 'DELETE' && !empty($this->body)) { parse_str($this->body, $bodyParams); $params = array_merge($params, $bodyParams); } return $params; } // Bonus: Add a method for JSON bodies across all methods public function jsonVars() { $contentType = $this->getHeader('Content-Type'); if (strpos($contentType, 'application/json') === false) { return []; } $params = json_decode($this->body, true); return is_array($params) ? $params : []; } }
Now you can use $request->putVars() or $request->deleteVars() exactly like you use the built-in methods.
A quick note on DELETE requests
It’s worth mentioning that some APIs pass DELETE parameters in the URL query string instead of the body. In those cases, you can just use $request->getVars() directly—no need to parse the body at all. The deleteVars() method above accounts for both scenarios by merging URL and body params.
内容的提问来源于stack exchange,提问作者HardMagnett

