Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 不同Laravel控制器之间的通用逻辑方法_Php_Laravel_Laravel 5 - Fatal编程技术网

Php 不同Laravel控制器之间的通用逻辑方法

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

假设我有这样一个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 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)也许会更好,这样我们就可以只在我们需要的路径上调用它。我不明白为什么你认为这不适合中间件。这正是中间件应该使用的功能。有趣的是,尽管这与我的解决方案没有太大区别,但我也可以将我的方法声明为静态,并从任何地方调用。非常有趣的是,除了检查之外,我的方法还返回一些数据(城市的行)。我认为我不能告诉中间件将数据传递给控制器,或者我可以吗?你可以解决这个问题,使用会话或其他某种全局存储来传递数据,但这不是中间件的真正目的。如果调用函数来获取一些数据,那么应该将其保留在控制器中,或者最好将其移动到模型或存储库/帮助器类中。