Laravel 5 如何验证路由参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30238285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 5 how to validate route parameters?
提问by JBP
I want to validate the route parameters in the "form request" but don't know how to do it.
我想验证“表单请求”中的路由参数,但不知道该怎么做。
Below is the code sample, I am trying with:
下面是代码示例,我正在尝试:
Route
路线
// controller Server
Route::group(['prefix' => 'server'], function(){
Route::get('checkToken/{token}',['as'=>'checkKey','uses'=> 'ServerController@checkToken']);
});
Controller
控制器
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests;
class ServerController extends Controller {
public function checkToken( \App\Http\Requests\CheckTokenServerRequest $request) // OT: - why I have to set full path to work??
{
$token = Token::where('token', '=', $request->token)->first();
$dt = new DateTime;
$token->executed_at = $dt->format('m-d-y H:i:s');
$token->save();
return response()->json(json_decode($token->json),200);
}
}
CheckTokenServerRequest
校验令牌服务器请求
namespace App\Http\Requests;
use App\Http\Requests\Request;
class CheckTokenServerRequest extends Request {
//autorization
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'token' => ['required','exists:Tokens,token,executed_at,null']
];
}
}
But when I try to validate a simple url http://myurl/server/checkToken/222, I am getting the response: no " token " parameter set
.
但是当我尝试验证一个简单的 url http://myurl/server/checkToken/222 时,我得到了响应: no " token " parameter set
。
Is it possible to validate the parameters in a separate "Form request", Or I have to do all in a controller?
是否可以在单独的“表单请求”中验证参数,或者我必须在控制器中完成所有操作?
ps. Sorry for my bad English.
附:对不起,我的英语不好。
回答by Marcin Nabia?ek
For Laravel < 5.5:
The way for this is overriding all()
method for CheckTokenServerRequest
like so:
对于 Laravel < 5.5:
这样做的all()
方法是CheckTokenServerRequest
像这样覆盖方法:
public function all()
{
$data = parent::all();
$data['token'] = $this->route('token');
return $data;
}
EDIT
For Laravel >= 5.5:
Above solution works in Laravel < 5.5. If you want to use it in Laravel 5.5 or above, you should use:
编辑
对于 Laravel >= 5.5:
上述解决方案适用于Laravel < 5.5。如果你想在Laravel 5.5 或更高版本中使用它,你应该使用:
public function all($keys = null)
{
$data = parent::all($keys);
$data['token'] = $this->route('token');
return $data;
}
instead.
反而。
回答by Mahmoud Zalt
Override the all()
function on the Request object to automatically apply validation rules to the URL parameters
覆盖all()
Request 对象上的函数以自动将验证规则应用于 URL 参数
class SetEmailRequest
{
public function rules()
{
return [
'email' => 'required|email|max:40',
'id' => 'required|integer', // << url parameter
];
}
public function all()
{
$data = parent::all();
$data['id'] = $this->route('id');
return $data;
}
public function authorize()
{
return true;
}
}
Access the data normally from the controller like this, after injecting the request:
在注入请求后,像这样从控制器正常访问数据:
$setEmailRequest->email // request data
$setEmailRequest->id, // url data
回答by Salar
The form request validators are used for validating HTML form datathat are sent to server via POSTmethod. It is better that you do not use them for validating route parameters. route parameters are mostly used for retrieving data from data base so in order to ensure that your token route parameter is correct change this line of your code, from
表单请求验证器用于验证通过POST方法发送到服务器的HTML 表单数据。最好不要使用它们来验证路由参数。路由参数主要用于从数据库中检索数据,因此为了确保您的令牌路由参数正确,请更改代码中的这一行,从
$token = Token::where('token', '=', $request->token)->first();
to
到
$token = Token::where('token', '=', $request->input(token))->firstOrFail();
firstOrFail() is a very good function, it sends 404 to your user, if the user insert any invalid token.
firstOrFail() 是一个非常好的函数,如果用户插入任何无效令牌,它会向您的用户发送 404。
you get no " token " parameter set
because Laravel assumes that your "token" parameter is a POST data which in your case it is not.
你得到no " token " parameter set
是因为 Laravel 假设你的“令牌”参数是一个 POST 数据,而在你的情况下它不是。
if you insist on validating your "token" parameter, by form request validators you gonna slow down your application, because you perform twoqueries to your db, one in here
如果你坚持验证你的“令牌”参数,通过表单请求验证器你会减慢你的应用程序,因为你对你的数据库执行了两个查询,一个在这里
$token = Token::where('token', '=', $request->token)->first();
and one in here
和一个在这里
return [
'token' => ['required','exists:Tokens,token,executed_at,null']
];
I suggest to use firsOrFailto do both validatingand retrievingat once.
我建议使用firsOrFail做到既验证和检索一次。
回答by mk_
If you dont want to specify each route param and just put all route params you can override like this:
如果您不想指定每个路由参数而只是放置所有路由参数,您可以像这样覆盖:
Laravel < 5.5:
Laravel < 5.5:
public function all()
{
return array_merge(parent::all(), $this->route()->parameters());
}
Laravel 5.5 or above:
Laravel 5.5 或更高版本:
public function all($keys = null)
{
// Add route parameters to validation data
return array_merge(parent::all(), $this->route()->parameters());
}
回答by Tarek Adam
A trait can cause this validation to be relatively automagic.
特征可以使这种验证相对自动化。
Trait
特征
<?php
namespace App\Http\Requests;
/**
* Class RouteParameterValidation
* @package App\Http\Requests
*/
trait RouteParameterValidation{
/**
* @var bool
*/
private $captured_route_vars = false;
/**
* @return mixed
*/
public function all(){
return $this->capture_route_vars(parent::all());
}
/**
* @param $inputs
*
* @return mixed
*/
private function capture_route_vars($inputs){
if($this->captured_route_vars){
return $inputs;
}
$inputs += $this->route()->parameters();
$inputs = self::numbers($inputs);
$this->replace($inputs);
$this->captured_route_vars = true;
return $inputs;
}
/**
* @param $inputs
*
* @return mixed
*/
private static function numbers($inputs){
foreach($inputs as $k => $input){
if(is_numeric($input) and !is_infinite($inputs[$k] * 1)){
$inputs[$k] *= 1;
}
}
return $inputs;
}
}
Usage
用法
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyCustomRequest extends FormRequest{
use RouteParameterValidation;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(){
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(){
return [
//
'any_route_param' => 'required'//any rule(s) or custom rule(s)
];
}
}
回答by Hoàng ??ng
For \App\Http\Requests\CheckTokenServerRequest
you can add use App\Http\Requests\CheckTokenServerRequest;
at the top.
If you pass the token
by url
you can use it likes a variable in controller
.
因为\App\Http\Requests\CheckTokenServerRequest
你可以use App\Http\Requests\CheckTokenServerRequest;
在顶部添加。
如果你通过了token
由url
你可以用它喜欢在一个变量controller
。
public function checkToken($token) //same with the name in url
{
$_token = Token::where('token', '=', $token)->first();
$dt = new DateTime;
$_token->executed_at = $dt->format('m-d-y H:i:s');
$_token->save();
return response()->json(json_decode($token->json),200);
}
回答by Cristo
You just missing the underscore before token. Replace with
您只是在标记之前缺少下划线。用。。。来代替
_token
_令牌
wherever you check it against the form generated by laravel.
无论您在何处根据 laravel 生成的表单检查它。
public function rules()
{
return [
'_token' => ['required','exists:Tokens,token,executed_at,null']
];
回答by Rene Berwanger
$request->merge(['id' => $id]);
...
$this->validate($request, $rules);
or
或者
$request->merge(['param' => $this->route('param')]);
...
$this->validate($request, $rules);
回答by Mladen Janjetovic
FormRequest has a method validationData()
that defines what data to use for validation. So just override that one with route parameters in your form request class:
FormRequest 有一个方法validationData()
来定义用于验证的数据。因此,只需在表单请求类中使用路由参数覆盖那个:
/**
* Use route parameters for validation
* @return array
*/
protected function validationData()
{
return $this->route()->parameters();
}
回答by Paul Rysevets
or leave most of the all
logic in place and override input
method from trait \Illuminate\Http\Concerns\InteractsWithInput
或保留大部分all
逻辑并覆盖input
方法trait \Illuminate\Http\Concerns\InteractsWithInput
/**
* Retrieve an input item from the request.
*
* @param string|null $key
* @param string|array|null $default
* @return string|array|null
*/
public function input($key = null, $default = null)
{
return data_get(
$this->getInputSource()->all() + $this->query->all() + $this->route()->parameters(), $key, $default
);
}