Laravel 5 - Routes and Variable Parameters in Controllers

I want to generate SEO friendly URLs like this when searching:
http://www.example.com/search (no filters)
Http: //**www.example.com/search/region-filter
Http: // ** www.example.com / search / region-filter / city-filter

And to break them down like this:
http://www.example.com/search/2 (no filters, page 2)
Http: //**www.example.com/search/region-filter/2
Http: // ** www.example.com / search / region-filter / city-filter / 2

(sorry, I cannot post more than 2 links due to reputation)

So the second segment can be a filter or a number of pages (and the same with the third).

My My Laravel 5 routing file:

Route::pattern('page', '[0-9]+');
...
Route::get('search/{region}/{city}/{page?}', 'SearchController@index');
Route::get('search/{region}/{page?}', 'SearchController@index');
Route::get('search/{page?}', 'SearchController@index');

      

The routes work fine because of the 'page' pattern, but inside a controller, this petition http: //**www.example.com/search/2 maps {page} to $ region (even using the last routing rule):

public function index($region='', $city='', $page='')

      

Codeigniter parameters are displayed by name, but it looks like Laravel matches them by position, so I always get the first one in $ region.

Is it possible to route parameters by name instead of position, or use some Laravel alternative to get them in the controller? (I can count segments, but this is an ugly solution for me)

+3


source to share


1 answer


You can use the method Route::current()

to access the current route and get parameters by name parameter method

. However, there are problems with route definitions that would render the last two routes useless as defined.

Since the parameter page

on the last two routes is optional, depending on the path of the route, your second and third routes will not match properly due to ambiguous route definitions. Below is a test case to support my point.


If you were to have this in your controller:

public function index()
{
    $route = \Route::current();

    $region = $route->parameter('region');
    $city = $route->parameter('city');
    $page = $route->parameter('page');

    $params = [
        'region' => $region,
        'city' => $city,
        'page' => $page
    ];

    return $params;
}

      

You will receive the following results for each route:

1. For example.com/search/myregion/mycity/mypage

:

{
    "region": "myregion",
    "city": "mycity",
    "page": "mypage"
}

      



2. For example.com/search/myregion/mypage

:

{
    "region": "myregion",
    "city": "mypage",
    "page": null
}

      

3. For example.com/search/mypage

:

{
    "region": "mypage",
    "city": null,
    "page": null
}

      

So, your problem is not matching the parameters by order or by name, but with the route definitions. To fix this, you can simply specify the pagination in the query string and discard the route definitions entirely, because there is absolutely nothing wrong with having your pagination as a query string parameter if it is optional anyway. So your url will look like this:

example.com/search/myregion/mycity?page=2

      

You can check the Illuminate \ Routing \ Route API of the class to see what other methods you have there.

+6


source







All Articles