如何声明显式期望这样的两个查询参数的路由和控制器方法?

时间:2017-03-02 18:48:18

标签: php laravel laravel-5 laravel-5.3 laravel-routing

我在 Laravel 中相当新,我遇到以下问题。

我必须声明一个处理这样的请求的路由:

http://laravel.dev/activate?email=myemail@gmail.com&token=eb0d89ba7a277621d7f1adf4c7803ebc

因此,此网址必须以格式激活作为资源和2个查询参数,格式为?电子邮件&令牌。这不是REST URI。我需要以这种方式使用它。)

我需要一个处理这种请求的路由和控制器方法。

我知道我可以这样做:

1)进入 routes / web.php 文件,我声明了这样的溃败

Route::get('/activate','MyController@myMethod');

2)进入 MyController ,我声明了这个方法:

public function myMethod(Request $request) {

    if(Input::has('email') && Input::has('token')) {
        $email = $request->input('email');
        $token= $request->input('token');

        // DO SOMETHING USING $email AND $token
    }
    else {
        // SHOW ERROR PAGE
    }
}

但我发现它非常可怕。我来自Java并使用Spring框架,我可以在URL和控制器方法之间的映射中指定一个方法处理对资源的请求,并且必须传递一些特定的查询参数。否则(如果这些参数不存在,则控制器方法不处理HTTP GET请求。)

我知道在Laravel中我可以使用我的URL的 REST 形式做这样的事情,我想是这样的:

路线映射:

Route::get('/activate/{email}/{token}', [ 'uses' => 'ActivationController@activate', 'as' => 'activate' ]);

然后控制器方法将是这样的:

public function activate($email, $token) {
    // $email would be 'myemail@gmail.com'
    // $token would be 'eb0d89ba7a277621d7f1adf4c7803ebc'
    // do stuff...
}

但在这种情况下我不能使用这种URI(因为指定的URL模式必须采用以下格式:

  

http://laravel.dev/activate email=myemail@gmail.com &安培;?的标记= eb0d89ba7a277621d7f1adf4c7803ebc

所以我希望用这种URI做这样的事情。我不会将 Request $ request 对象传递给我的控制器方法,然后从中提取参数,但我希望有一个像这样的控制器方法签名:

public function activate($email, $token) {

其中如果未传递所有预期参数,则该控制器将不会处理该请求。

我更喜欢这样做,因为对我来说这是一个更简洁的方法(读取控制器签名,另一个开发人员立即知道这个方法是期望的)。

还因为我希望方法不处理格式错误的参数(所以我可以避免处理错误情况,例如:用户不传递2个参数)。

我怎样才能在Laravel中做这样的事情? (如果有可能......)

1 个答案:

答案 0 :(得分:0)

这当然是一个奇怪的请求,因为它无视更传统的Laravel路由实践,但这应该对你有用:

routes.php(Laravel< 5.3)或web.php(Laravel 5.4 +)中:

Route::get('/activate', [ 'as' => 'activate', function()
{
    return app()->make(App\Http\Controllers\ActivateController::class)->callAction('activate', $parameters = [ 'email' => request()->email, 'token' => request()->token ]);
}]);

所以我们实例化ActivateController类并调用方法'activate'这是第一个参数,然后提供方法以数组形式接收的参数列表。

public function activate($email, $token)
{
    echo "Email: $email"; // myemail@gmail.com
    echo "Token: $token"; // eb0d89ba7a277621d7f1adf4c7803ebc
    // do stuff
}

现在,只要您转到http://laravel.dev/activate?email=myemail@gmail.com&token=eb0d89ba7a277621d7f1adf4c7803ebc $email$token将成为相应的关键查询参数。

现在,至于验证以确保数据存在。您必须在activate()方法中添加另一个参数,除非您想要内联。

最佳做法:

运行php artisan make:request ActivateRequest

将在app\Http\Requests中创建一个名为ActivateRequest的新文件。打开它并确保您的authorize()方法返回true,如下所示:

public function authorize()
{
    return true;
}

接下来,在rules()方法中有一个数组。添加以下内容:

return [
    'email' => 'required|email',
    'token' => 'required',
];

如果您想为这些规则提供自己的验证消息,请在rules() messages()下方添加名为public function messages() { return [ 'email.required' => 'You must supply an email address.', 'email.email' => 'That email is address is not valid.', 'token.required' => 'Please supply a token.', ]; } 的方法,如下所示:

ActivateController

然后,回到use App\Http\Requests\ActivateRequest;,在最新的activate($email, $token, ActivateRequest $request) { ... 拉入新的FormRequest类,并在方法中使用它,如下所示:

$request

现在,您的请求将得到验证,您甚至不必使用Validator变量。

内联(不是最佳实践方式)

如果您在方法中没有额外的参数 dead set ,则可以像这样验证控制器中的数据:

首先,在顶部引入use Validator;课程。 public function activate($email, $token) { $validationMessages = [ 'email.required' => 'You must supply an email address.', 'email.email' => 'That email is address is not valid.', 'token.required' => 'Please supply a token.', ]; $validation = Validator::make(request()->toArray(), [ 'email.required' => 'You must supply an email address.', 'email.email' => 'That email is address is not valid.', 'token.required' => 'Please supply a token.', ], $validationMessages); if ( $validation->fails() ) { return 'Sorry, there was a problem with your request'; } // do stuff }

<head>
  <meta charset="utf-8" />
  <title>
    <!-- Title here -->
  </title>
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />
  <link rel="stylesheet" href="style.css" />
  <script src="https://code.jquery.com/jquery-1.6.min.js"></script>
  <script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
  <script src="./nicedit.js"></script>
</head>

<body>
  <textarea id="editor"></textarea>
  <div id="dialog">
    <textarea id="editorInDialog"></textarea>
  </div>
  <input type="button" id="test" value="open modal dialog" />
  <script>
    $('#test').click(function() {
      $("#dialog").dialog("open");
    });
    $('#dialog').dialog({
      autoOpen: false,
      modal: true,
      open: function() {
        new nicEditor({
          fullPanel: true,
          iconsPath: 'https://cdn.jsdelivr.net/nicedit/0.9r24/nicEditorIcons.gif'
        }).panelInstance('editorInDialog');
      }
    });

    new nicEditor({
      fullPanel: true,
      iconsPath: 'https://cdn.jsdelivr.net/nicedit/0.9r24/nicEditorIcons.gif'
    }).panelInstance('editor');
  </script>
</body>

希望这会有所帮助。