在Laravel中将固定变量从路由传递到控制器 [英] Pass fixed variable from route to controller in Laravel

查看:68
本文介绍了在Laravel中将固定变量从路由传递到控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过路由将变量传递给控制器​​,但是我有多个路由(类别)通向同一控制器,即

I'm trying to pass a variable through my route to my controller, but I have multiple routes (categories) leading to the same controller i.e.

Route::get('/category1/{region}/{suburb?}', 'SearchController@search');
Route::get('/category2/{region}/{suburb?}', 'SearchController@search');

不允许将/category1、2等作为参数/{category},并且我不想为每个类别设置单独的控制器功能.

Making /category1, 2, etc. to be a parameter /{category} is not an option and I don't want to make separate controller function for each category.

如何将网址的第一部分发送到我的搜索控制器?即category1或category2?

How do I send the first segment of the url to my search controller? i.e. category1 or category2?

目前的控制器如下:

public function search($region, $suburb = null) { }

谢谢!

推荐答案

您可以为{category}参数指定一个掩码,以便该掩码必须适合"category [0-9] +"格式才能匹配路由.

You can specify a mask for your {category} parameter so that it must fit the format "category[0-9]+" in order to match the route.

Route::get('/{category}/{region}/{suburb?}', 'SearchController@search')
    ->where('category', 'category[0-9]+');

现在,您的示例网址(来自注释)www.a.com/var1/var2/var3仅在var1匹配给定类别正则表达式时匹配路由.

Now, your example url (from the comments) www.a.com/var1/var2/var3 will only match the route if var1 matches the given category regex.

有关详细信息,请参见文档此处.

More information can be found in the documentation for route parameters here.

是的,这可以使用字符串值数组.这是一个正则表达式,因此您只需要将字符串值数组放入该上下文中即可:

Yes, this can work with an array of string values. It is a regex, so you just need to put your array of string values into that context:

Route::get('/{category}/{region}/{suburb?}', 'SearchController@search')
    ->where('category', 'hairdresser|cooper|fletcher');

或者,如果您在其他位置构建了阵列:

Or, if you have the array built somewhere else:

$arr = ['hairdresser', 'cooper', 'fletcher'];

// run each array entry through preg_quote and then glue
// the resulting array together with pipes
Route::get('/{category}/{region}/{suburb?}', 'SearchController@search')
    ->where('category', implode('|', array_map('preg_quote', $arr)));

编辑2(原始请求的解决方案)

您最初的问题是如何将硬编码的类别段传递到控制器中.如果由于某种原因您不希望使用上述解决方案,则可以选择其他两种选择.

Edit 2 (solutions for original request)

Your original question was how to pass the hardcoded category segment into the controller. If, for some reason, you didn't wish to use the solution above, you have two other options.

选项1:,不要传递值,只需在控制器中访问请求的分段即可.

Option 1: don't pass the value in, just access the segments of the request in the controller.

public function search($region, $suburb = null) {
    $category = \Request::segment(1);
    dd($category);
}

选项2:使用前置过滤器(L4)或前置中间件(L5)修改路由参数.

Option 2: modify the route parameters using a before filter (L4) or before middleware (L5).

在过滤器(和中间件)可以访问路由对象之前,可以使用路由对象上的方法来修改路由参数.这些路由参数最终传递到控制器操作中.路线参数存储为关联数组,因此在尝试正确获取订单时必须牢记.

Before filters (and middleware) have access to the route object, and can use the methods on the route object to modify the route parameters. These route parameters are eventually passed into the controller action. The route parameters are stored as an associative array, so that needs to be kept in mind when trying to get the order correct.

如果使用Laravel 4,则需要一个前置过滤器.定义路由以使用before过滤器,并传递要添加到参数中的硬编码值.

If using Laravel 4, you'd need a before filter. Define the routes to use the before filter and pass in the hardcoded value to be added onto the parameters.

Route::get('/hairdresser/{region}/{suburb?}', ['before' => 'shiftParameter:hairdresser', 'uses' => 'SearchController@search']);
Route::get('/cooper/{region}/{suburb?}', ['before' => 'shiftParameter:cooper', 'uses' => 'SearchController@search']);
Route::get('/fletcher/{region}/{suburb?}', ['before' => 'shiftParameter:fletcher', 'uses' => 'SearchController@search']);

Route::filter('shiftParameter', function ($route, $request, $value) {
    // save off the current route parameters    
    $parameters = $route->parameters();
    // unset the current route parameters
    foreach($parameters as $name => $parameter) {
        $route->forgetParameter($name);
    }

    // union the new parameters and the old parameters
    $parameters = ['customParameter0' => $value] + $parameters;
    // loop through the new set of parameters to add them to the route
    foreach($parameters as $name => $parameter) {
        $route->setParameter($name, $parameter);
    }
});

如果使用Laravel 5,则需要在中间件之前定义一个新的.将新类添加到app/Http/Middleware目录,并将其注册到app/Http/Kernel.php的$routeMiddleware变量中.逻辑基本上是相同的,但要经过额外的循环才能将参数传递给中间件.

If using Laravel 5, you'd need to define a new before middleware. Add the new class to the app/Http/Middleware directory and register it in the $routeMiddleware variable in app/Http/Kernel.php. The logic is basically the same, with an extra hoop to go through in order to pass parameters to the middleware.

// the 'parameters' key is a custom key we're using to pass the data to the middleware
Route::get('/hairdresser/{region}/{suburb?}', ['middleware' => 'shiftParameter', 'parameters' => ['hairdresser'], 'uses' => 'SearchController@search']);
Route::get('/cooper/{region}/{suburb?}', ['middleware' => 'shiftParameter', 'parameters' => ['cooper'], 'uses' => 'SearchController@search']);
Route::get('/fletcher/{region}/{suburb?}', ['middleware' => 'shiftParameter', 'parameters' => ['fletcher'], 'uses' => 'SearchController@search']);

// middleware class to go in app/Http/Middleware
// generate with "php artisan make:middleware" statement and copy logic below
class ShiftParameterMiddleware {
    public function handle($request, Closure $next) {
        // get the route from the request
        $route = $request->route();

        // save off the current route parameters
        $parameters = $route->parameters();
        // unset the current route parameters
        foreach ($parameters as $name => $parameter) {
            $route->forgetParameter($name);
        }

        // build the new parameters to shift onto the array
        // from the data passed to the middleware
        $newParameters = [];
        foreach ($this->getParameters($request) as $key => $value) {
            $newParameters['customParameter' . $key] = $value;
        }

        // union the new parameters and the old parameters
        $parameters = $newParameters + $parameters;
        // loop through the new set of parameters to add them to the route
        foreach ($parameters as $name => $parameter) {
            $route->setParameter($name, $parameter);
        }

        return $next($request);
    }

    /**
     * Method to get the data from the custom 'parameters' key added
     * on the route definition.
     */
    protected function getParameters($request) {
        $actions = $request->route()->getAction();
        return $actions['parameters'];
    }
}

现在,随着过滤器(或中间件)的设置和使用,该类别将作为第一个参数传递到控制器方法中.

Now, with the filter (or middleware) setup and in use, the category will be passed into the controller method as the first parameter.

public function search($category, $region, $suburb = null) {
    dd($category);
}

这篇关于在Laravel中将固定变量从路由传递到控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆