问题
I am creating an API for Laravel. I use the PUT method for updating data.
I send data with Postman using the PUT method. In my controller, I got an empty array. How to access the passed data?
In my route, I have:
Route::put('vehicletypes/{id}','API\VehicletypeController@update');
In my controller:
public function update(Request $request, $id){
print_r($request->all()); exit;
}
How to get the data passed in PUT method?
回答1:
You are getting empty response because PHP have some security restrictions against PUT. But Laravel have a workaround for this.
So, to solve this you have to send a POST
request from Postman instead, with a POST
param __method
with value PUT
. And it should work.
回答2:
Laravel cheats because html forms only support GET and POST, but it does understand a real PUT/PATCH request.
The problem looks like lies in Symfony it can't parse the data if it's multipart/form-data, as an alternative try using x-www-form-urlencoded content disposition.
回答3:
public function putUpdate(Request $request, $id){
print_r($request->all()); exit;
}
And change route too,
Route::put('vehicletypes/{id}','API\VehicletypeController@putUpdate');
回答4:
Why nobody is giving clear explanation at first put method field of
{{method_field('put')}}
as your router uri is that is displayed using command
php artisan router:list
of update method is put/patch so first add
{{method_field('put')}}
and field in your form should be the same
<form action="{{route('posts.update',$post->id)}}" method="post">
after adding the csrf_toke form will be working. and final shape would be as below of form.
<form action="{{route('posts.update',$post->id)}}" method="post" >
{{method_field('put')}}
<input type="hidden" name="_token" value="{{csrf_token()}}">
<!-- Name input-->
<div class="form-group">
<label class="col-md-3 control-label" for="name">Title</label>
<div class="col-md-9">
<input id="name" name="title" type="text" value="{{$post->title}}" class="form-control">
</div>
</div>
<!-- Message body -->
<div class="form-group">
<label class="col-md-3 control-label" for="body">
Body</label><br>
<div class="col-md-9">
<textarea class="form-control" id="message" name="body" rows="5">
{{$post->body}}
</textarea>
</div>
</div>
<!-- Form actions -->
<div class="form-group">
<div class="col-md-9 text-right col-md-offset-3">
<button type="submit" class="btn btn-success btn-lg">Update</button>
<a href="{{Route('posts.index')}}" type="button" class="btn btn-primary btn-lg">Cancel</a>
</div>
</div>
</form>
回答5:
Checked "x-www-form-urlencoded" instead of "form-data" under body tab in the Postman, the put methood will work as well...
回答6:
Following link will resolve the issue to get the request form data plus the images.
If you are working on Laravel, you can easily parse and bind the form params in the \Illuminate\Http\Request Instance
Simply just get the ParseInputStream Class from the link below:
Class ParseInputStream.php
Create another Validation Rule Class in Laravel optional but not required,
class NoteUpdateRequest extends Request {
public function all($keys = null)
{
if(strtolower($this->getMethod())=='put' && preg_match('/multipart\/form-data/', $this->headers->get('Content-Type')) or
preg_match('/multipart\/form-data/', $this->headers->get('content-type')))
{
$result = [];
new ParseInputStream($result);
$result = array_merge($result, $this->route()->parameters());
$this->request->add($result);
}
return parent::all($keys);
}
public function rules()
{
dd($this->all());
return [
'noteId' => 'required|integer|exists:notes,id',
'title' => 'required|string|max:200',
'note' => 'required|string|min:10|max:2000'
];
}
}
I hope it resolved what you want to achieve, using PUT or PATCH method along with Form Params
回答7:
As mentioned, this isn't a laravel (or symfony, or any other framework) issue, it's a limitation of PHP.
After trawling through a good few RFCs for php core, the core development team seem somewhat resistant to implementing anything to do with modernising the handling of HTTP requests. The issue was first reported in 2011, it doesn't look any closer to having a native solution.
That said, I managed to find this PECL extension. I'm not really very familiar with pecl, and couldn't seem to get it working using pear. but I'm using CentOS and Remi PHP which has a yum package.
I ran yum install php-pecl-apfd
and it literally fixed the issue straight away (well I had to restart my docker containers but that was a given).
That is, request->all()
and files->get()
started working again with PATCH and PUT requests using multipart/form-data
.
Ergo, I managed to get my api playing nicely with my front-end without adding any quirks (that would need to be relayed to anybody developing front-end solutions) or breaking RESTful conventions.
I believe there are other packages in various flavours of linux and I'm sure anybody with more knowledge of pear/pecl/general php extensions could get it running on windows or mac with no issue.
来源:https://stackoverflow.com/questions/47694722/how-to-get-data-passed-from-put-method