Let's say I have an URL like this:
/city/nyc (display info about new york city)
and another like this:
/city/nyc/streets (display a list of Street of nyc)
I can bind them to a method like this:
Route::get('city/{city}', 'CityController@showCity');
Route::get('city/{city}/streets', 'CityController@showCityStreet');
The problem is that I need to execute some checks on the city (for example if {city} is present in the database) on both methods. I could create a method and call them in both like this:
class CityController {
private function cityCommonCheck($city) {
// check
}
public function showCity($city) {
$this->cityCommonCheck($city);
// other logic
}
public function showCityStreet($city) {
$this->cityCommonCheck($city);
// other logic
}
}
Is there any better way?
I think best way to do this, you can move common logic into a Model.So your code would like below.
class CityController {
public function showCity($city) {
City::cityCommonCheck($city);
}
public function showCityStreet($city) {
City::cityCommonCheck($city);
}
}
class City{
public static function cityCommonCheck($city) {
//put here your logic
}
}
In this way you could invoke cityCommonCheck function from any controller.
Even though you think differently, I believe a middleware is the best solution for this.
First, use php artisan make:middleware CityCheckMiddleware
to create a class in App/Http/Middleware
. Then edit the method to do what your check is supposed to do and add a constructor to inject the Router
public function __construct(\Illuminate\Http\Routing\Router $router){
$this->route = $router;
}
public function handle($request, Closure $next)
{
$city = $this->route->input('city');
// do checking
return $next($request);
}
Define a shorthand key in App/Http/Kernel.php
:
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
// ...
'city_checker' => 'App\Http\Middleware\CityCheckerMiddleware',
];
Then, in your controller:
public function __construct()
{
$this->middleware('city_checker', ['only' => ['showCity', 'showCityStreet']]);
}