花了2个小时,挖掘谷歌和Laravel的源代码后,我想出了这个解决方案,我觉得这个解决方案效果最好,看起来最干净。无需重定向和多个内部请求。
您可以在路径文件的最底部添加此路线。
如果没有匹配其他路由,则执行此操作。在闭包中,您可以决定执行哪个控制器和操作。
最好的部分是 - 所有路由参数都传递给action,方法注入仍然有效。 ControllerDispatcer行来自Laravel Route(r?)类。
我的例子将处理2个案例 - 首先检查用户是否存在该名称,然后检查slug是否可以找到文章。
Laravel 5.2(5.3以下)
Route::get('{slug}/{slug2?}', function ($slug) {
$class = false;
$action = false;
$user = UserModel::where('slug', $slug)->first();
if ($user) {
$class = UserController::class;
$action = 'userProfile';
}
if (!$class) {
$article= ArticleModel::where('slug', $slug)->first();
if ($article) {
$class = ArticleController::class;
$action = 'index';
}
}
if ($class) {
$route = app(\Illuminate\Routing\Route::class);
$request = app(\Illuminate\Http\Request::class);
$router = app(\Illuminate\Routing\Router::class);
$container = app(\Illuminate\Container\Container::class);
return (new ControllerDispatcher($router, $container))->dispatch($route, $request, $class, $action);
}
// Some fallback to 404
throw new NotFoundHttpException;
});
5.3改变了控制器的调度方式。
这是5.3,5.4的动态控制器示例
namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use Illuminate\Routing\ControllerDispatcher;
use Illuminate\Routing\Route;
class DynamicRouteController extends Controller
{
/**
* This method handles dynamic routes when route can begin with a category or a user profile name.
* /women/t-shirts vs /user-slug/product/something
*
* @param $slug1
* @param null $slug2
* @return mixed
*/
public function handle($slug1, $slug2 = null)
{
$controller = DefaultController::class;
$action = 'index';
if ($slug1 == 'something') {
$controller = SomeController::class;
$action = 'myAction';
}
$container = app();
$route = $container->make(Route::class);
$controllerInstance = $container->make($controller);
return (new ControllerDispatcher($container))->dispatch($route, $controllerInstance, $action);
}
}
希望这有帮助!