Php 不同Laravel控制器之间的通用逻辑方法
假设我有这样一个URL:Php 不同Laravel控制器之间的通用逻辑方法,php,laravel,laravel-5,Php,Laravel,Laravel 5,假设我有这样一个URL: /city/nyc (display info about new york city) /city/nyc/streets (display a list of Street of nyc) Route::get('city/{city}', 'CityController@showCity'); Route::get('city/{city}/streets', 'CityController@showCityStreet'); class CityC
/city/nyc (display info about new york city)
/city/nyc/streets (display a list of Street of nyc)
Route::get('city/{city}', 'CityController@showCity');
Route::get('city/{city}/streets', 'CityController@showCityStreet');
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
}
}
还有一个是这样的:
/city/nyc (display info about new york city)
/city/nyc/streets (display a list of Street of nyc)
Route::get('city/{city}', 'CityController@showCity');
Route::get('city/{city}/streets', 'CityController@showCityStreet');
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
}
}
我可以将它们绑定到如下方法:
/city/nyc (display info about new york city)
/city/nyc/streets (display a list of Street of nyc)
Route::get('city/{city}', 'CityController@showCity');
Route::get('city/{city}/streets', 'CityController@showCityStreet');
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
}
}
问题是我需要对这两种方法执行一些城市检查(例如,如果数据库中存在{city})。
我可以创建一个方法并按如下方式调用它们:
/city/nyc (display info about new york city)
/city/nyc/streets (display a list of Street of nyc)
Route::get('city/{city}', 'CityController@showCity');
Route::get('city/{city}/streets', 'CityController@showCityStreet');
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
}
}
有更好的方法吗?我认为最好的方法是,您可以将公共逻辑移动到模型中
class CityController {
public function showCity($city) {
City::cityCommonCheck($city);
}
public function showCityStreet($city) {
City::cityCommonCheck($city);
}
}
模范班
通过这种方式,您可以从任何控制器调用cityCommonCheck函数。尽管您的想法不同,但我相信中间件是最好的解决方案 首先,使用
php-artisan-make:middleware-CityCheckMiddleware
在App/Http/middleware
中创建一个类。然后编辑该方法以执行您的检查应该执行的操作,并添加一个构造函数来注入路由器
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);
}
在App/Http/Kernel.php
中定义一个速记键:
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
// ...
'city_checker' => 'App\Http\Middleware\CityCheckerMiddleware',
];
然后,在控制器中:
public function __construct()
{
$this->middleware('city_checker', ['only' => ['showCity', 'showCityStreet']]);
}
你可以为itI写一个,我不认为中间件是最好的选择,我想把检查放在控制器的构造函数中,但是我怎么能从构造函数中访问{city}?你为什么这么认为?您可以使用route facade
route::input('city')
访问{city}
,或者通过注入Router
类$Router->input('city')
是的,在u构造函数中我可以使用route::input('city');但是如果我们把它放在一个单独的方法中(cityCommonCheck)也许会更好,这样我们就可以只在我们需要的路径上调用它。我不明白为什么你认为这不适合中间件。这正是中间件应该使用的功能。有趣的是,尽管这与我的解决方案没有太大区别,但我也可以将我的方法声明为静态,并从任何地方调用。非常有趣的是,除了检查之外,我的方法还返回一些数据(城市的行)。我认为我不能告诉中间件将数据传递给控制器,或者我可以吗?你可以解决这个问题,使用会话或其他某种全局存储来传递数据,但这不是中间件的真正目的。如果调用函数来获取一些数据,那么应该将其保留在控制器中,或者最好将其移动到模型或存储库/帮助器类中。