如何使用GET方法将GET参数传递到Laravel中?

39

我遇到了一个很基础的表单问题,无法完成。我想建立一个带有文本输入框和两个选择控件的搜索表单,并使用接受3个参数的路由。问题在于,当我提交表单时,它将参数映射到问号,而不是 Laravel 的方式。

Markup

{{ Form::open(['route' => 'search', 'method' => 'GET'])}}
    <input type="text" name="term"/>
    <select name="category" id="">
        <option value="auto">Auto</option>
        <option value="moto">Moto</option>
    </select>
    {{ Form::submit('Send') }}
{{ Form::close() }}

路由

    Route::get('/search/{category}/{term}', ['as' => 'search', 'uses' => 'SearchController@search']);

当我提交表单时,它会将我重定向到

search/%7Bcategory%7D/%7Bterm%7D?term=asdasd&category=auto

我该如何使用Laravel的方式,而不需要JavaScript,将这些参数传递给我的路由!:D

7个回答

43

最简单的方法就是接受传入的请求,并在控制器中提取您想要的变量:

Route::get('search', ['as' => 'search', 'uses' => 'SearchController@search']);

然后在SearchController@search中:

class SearchController extends BaseController {

    public function search()
    {
        $category = Input::get('category', 'default category');
        $term = Input::get('term', false);

        // do things with them...
    }
}

如果在传递给控制器的操作时没有任何值传递,可以在 Input::get() 中设置默认值

正如joe_archer所说,不必将这些术语放入URL中,使用POST可能更好(在这种情况下,您应该更新调用 Form :: open() 和 routes.php中的搜索路由- Input :: get() 保持不变)


编写代码时,始终要指定 Input 属于哪个命名空间。 - Akim Kelar

27

我也曾经遇到了这个问题,最后终于解决了。

routes.php

Route::get('people', 'PeopleController@index');
Route::get('people/{lastName}', 'PeopleController@show');
Route::get('people/{lastName}/{firstName}', 'PeopleController@show');
Route::post('people', 'PeopleController@processForm');

PeopleController.php

namespace App\Http\Controllers ;
use DB ;
use Illuminate\Http\Request ;
use App\Http\Requests ;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;

    public function processForm() {
        $lastName  = Input::get('lastName') ;
        $firstName = Input::get('firstName') ;
        return Redirect::to('people/'.$lastName.'/'.$firstName) ;
    }
    public function show($lastName,$firstName) {
        $qry = 'SELECT * FROM tableFoo WHERE LastName LIKE "'.$lastName.'" AND GivenNames LIKE "'.$firstName.'%" ' ;
        $ppl = DB::select($qry);
        return view('people.show', ['ppl' => $ppl] ) ;
    }

people/show.blade.php

<form method="post" action="/people">
    <input type="text" name="firstName" placeholder="First name">
    <input type="text" name="lastName" placeholder="Last name">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    <input type="submit" value="Search">
</form>

注意:
我需要将两个输入字段传递到URI中。
我还没有使用Eloquent,如果您正在使用,请相应地调整数据库逻辑。
而且我还没有完成保护用户输入的数据,所以请放心。
请注意“_token”隐藏表单字段和所有的“use”包含,它们是必需的。

PS:这是另一种似乎可行的语法,不需要

use Illuminate\Support\Facades\Input;

.

public function processForm(Request $request) {
    $lastName  = addslashes($request->lastName) ;
    $firstName = addslashes($request->firstName) ;
    //add more logic to validate and secure user entered data before turning it loose in a query
    return Redirect::to('people/'.$lastName.'/'.$firstName) ;
}

7
我知道这是一个旧的答案,但你永远不应该以这种方式进行查询,即使你不想遵循MVC架构,你应该始终使用Eloquent进行数据库查询。 - Mooncake

7

我有同样的问题。我需要为搜索引擎显示网址。

我使用了以下两个路由:

Route::get('buscar/{nom}', 'FrontController@buscarPrd');

Route::post('buscar', function(){

   $bsqd = Input::get('nom');    

   return Redirect::action('FrontController@buscarPrd', array('nom'=>$bsqd));

});

第一个用于显示我们想要的url

第二个用于表单并重定向到第一个


6

所以你想把搜索词和分类放到URL中?

我建议不要这样做,因为你将不得不处理多个单词的搜索词等等情况,并且可能会遇到使用不允许字符的各种问题。

我建议通过POST方式提交数据,对其进行净化处理,然后返回结果页面。

Laravel路由不是设计用于从表单接受GET请求的,它是设计用于在URL段上作为获取参数的,围绕这个思想构建的。


5

除了 msturdy的解决方案,你还可以使用可用的request helper方法

这种方法完全相同,无需在控制器顶部导入Input命名空间use Illuminate\Support\Facades\Input

例如:

class SearchController extends BaseController {

    public function search()
    {
        $category = request('category', 'default');
        $term = request('term'); // no default defined

        ...
    }
}

4

路由器

Route::get('search/{id}', ['as' => 'search', 'uses' => 'SearchController@search']);

控制器

class SearchController extends BaseController {

    public function search(Request $request){

        $id= $request->id ; // or any params

        ...
    }
}

1

或者,如果你想在操作签名中指定预期参数,但将它们作为任意 GET 参数传递。可以使用过滤器,例如:

创建一个没有参数的路由:

$Route::get('/history', ['uses'=>'ExampleController@history']);

使用两个参数指定操作并附加过滤器:

class ExampleController extends BaseController
{
    public function __construct($browser)
    {
        $this->beforeFilter('filterDates', array(
            'only' => array('history')
        ));
    }

    public function history($fromDate, $toDate)
    {
        /* ... */
    }

}

GET 转换为操作参数的过滤器:

Route::filter('filterDates', function($route, Request $request) {
    $notSpecified = '_';

    $fromDate = $request->get('fromDate', $notSpecified);
    $toDate = $request->get('toDate', $notSpecified);

    $route->setParameter('fromDate', $fromDate);
    $route->setParameter('toDate', $toDate);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接