在 Request 对象上重写 laravel 5.1 控制器动作路由
Rewriting laravel 5.1 controller action route on the Request object
我有很多模块,我的源代码组织到 App\Http\Controllers
内的子文件夹中,例如 App\Http\Controllers\ModuleOne
.
基本控制器在App\Http\Controllers
中,模块控制器扩展了这些基本控制器。如果我不想在使用特定模块时自定义基本控制器,则模块控制器可能不存在。
我想编写一个逻辑,其中路由检查模块控制器是否存在。如果路由不存在,它应该将操作路由到 BaseController
.
我尝试制作中间件和其他解决方案,但似乎无法完成。
我希望所有控制器内的路由都使用相同的名称(因此忽略模块名称 - 它将由环境变量定义)。所以,为了简化我想调用的代码:
Route::get('apple','AppleController@view')
从这条路线开始,它应该检查是否:
App\Http\Controller\module1\module1_AppleController.php
存在。
如果是,就使用它。如果不是,它应该路由到基本控制器操作,即 App\Http\Controller\AppleController
.
似乎无法弄清楚在哪里可以使用高效的代码来执行此操作。可以在 RouteServiceProvider
中间件或其他中完成重写吗?
另外,如果Laravel的较新版本可以提供5.1中没有的解决方案,我愿意升级,所以不要将答案限制在5.1。
如果你正确使用命名空间,你可以像那样组织你的控制器。通过从公共 BaseController 扩展 Controller 以实现特定逻辑,您可以执行如下操作:
<?php
namespace App\Http\Controllers\Default;
use Illuminate\Routing\Controller;
class MyFruitController extends Controller {
// Implement you callback methods, e.g.:
public function getApples() {}
public function getPeaches() {}
}
?>
在你的模块中:
<?php
namespace App\Http\Controllers\MyModuleA;
class MyFruitController extends \App\Http\Controllers\Default\MyFruitController {
// Implement those methods that should differ from default MyFruitController:
public function getApples() {}
// getPeaches() will be used from default MyFruitController
}
?>
并且:
<?php
namespace App\Http\Controllers\MyModuleB;
class MyFruitController extends \App\Http\Controllers\Default\MyFruitController {
// Implement those methods that should differ from default MyFruitController:
public function getPeaches() {}
// getApples() will be used from default MyFruitController
}
?>
您可以对您拥有的多个模块重复此操作。所以你有相同的控制器名称,只是命名空间不同。通过使用路由组和 env() 函数,您可以在 routes.php 文件中做一些很酷的事情:
<?php
...
// Fruits
Route::group([
'namespace' => env('module', 'Default'),
// And your other group options, like middleware, ..
], function () {
Route::get('apples', 'MyFruitController@getApples');
Route::get('peaches', 'MyFruitController@getPeaches');
});
...
?>
我有很多模块,我的源代码组织到 App\Http\Controllers
内的子文件夹中,例如 App\Http\Controllers\ModuleOne
.
基本控制器在App\Http\Controllers
中,模块控制器扩展了这些基本控制器。如果我不想在使用特定模块时自定义基本控制器,则模块控制器可能不存在。
我想编写一个逻辑,其中路由检查模块控制器是否存在。如果路由不存在,它应该将操作路由到 BaseController
.
我尝试制作中间件和其他解决方案,但似乎无法完成。
我希望所有控制器内的路由都使用相同的名称(因此忽略模块名称 - 它将由环境变量定义)。所以,为了简化我想调用的代码:
Route::get('apple','AppleController@view')
从这条路线开始,它应该检查是否:
App\Http\Controller\module1\module1_AppleController.php
存在。
如果是,就使用它。如果不是,它应该路由到基本控制器操作,即 App\Http\Controller\AppleController
.
似乎无法弄清楚在哪里可以使用高效的代码来执行此操作。可以在 RouteServiceProvider
中间件或其他中完成重写吗?
另外,如果Laravel的较新版本可以提供5.1中没有的解决方案,我愿意升级,所以不要将答案限制在5.1。
如果你正确使用命名空间,你可以像那样组织你的控制器。通过从公共 BaseController 扩展 Controller 以实现特定逻辑,您可以执行如下操作:
<?php
namespace App\Http\Controllers\Default;
use Illuminate\Routing\Controller;
class MyFruitController extends Controller {
// Implement you callback methods, e.g.:
public function getApples() {}
public function getPeaches() {}
}
?>
在你的模块中:
<?php
namespace App\Http\Controllers\MyModuleA;
class MyFruitController extends \App\Http\Controllers\Default\MyFruitController {
// Implement those methods that should differ from default MyFruitController:
public function getApples() {}
// getPeaches() will be used from default MyFruitController
}
?>
并且:
<?php
namespace App\Http\Controllers\MyModuleB;
class MyFruitController extends \App\Http\Controllers\Default\MyFruitController {
// Implement those methods that should differ from default MyFruitController:
public function getPeaches() {}
// getApples() will be used from default MyFruitController
}
?>
您可以对您拥有的多个模块重复此操作。所以你有相同的控制器名称,只是命名空间不同。通过使用路由组和 env() 函数,您可以在 routes.php 文件中做一些很酷的事情:
<?php
...
// Fruits
Route::group([
'namespace' => env('module', 'Default'),
// And your other group options, like middleware, ..
], function () {
Route::get('apples', 'MyFruitController@getApples');
Route::get('peaches', 'MyFruitController@getPeaches');
});
...
?>