Laravel有一个很棒的路由系统,但我有一点特别困难。
在为路由定义控制器时,我希望删除创建的额外可选路由。
在Laravel 3中,您显然可以做以下工作,但从未使用过v3,我不知道这是否是我想要的,无论如何,它在v4中不起作用。
Router::$segments = 0;例如,当我像这样定义我的路线时:
Route::group(array('prefix' => 'monitoring'), function() {
// Handle hosts
Route::controller('hosts/', 'Apm\Controllers\Monitoring\Hosts\Index');
Route::controller('hosts/{host}', 'Apm\Controllers\Monitoring\Hosts\Host');
Route::controller('hosts/{host}/{service}', 'Apm\Controllers\Monitoring\Hosts\Service');
});我的路径将在artisan routes命令中这样显示:
+--------+------------------------------------------------------------------------------------------------+------+---------------------------------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+------------------------------------------------------------------------------------------------+------+---------------------------------------------------------+----------------+---------------+
| | GET|HEAD / | | Closure | | |
| | GET|HEAD monitoring/hosts/status/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Index@getStatus | | |
| | GET|HEAD monitoring/hosts/details/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Index@getDetails | | |
| | GET|HEAD monitoring/hosts/report/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Index@getReport | | |
| | GET|HEAD monitoring/hosts/thresholds/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Index@getThresholds | | |
| | GET|HEAD monitoring/hosts/timeline/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Index@getTimeline | | |
| | GET|HEAD monitoring/hosts/index/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Index@getIndex | | |
| | GET|HEAD monitoring/hosts | | Apm\Controllers\Monitoring\Hosts\Index@getIndex | | |
| | GET|HEAD monitoring/hosts/{host}/status/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Host@getStatus | | |
| | GET|HEAD monitoring/hosts/{host}/details/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Host@getDetails | | |
| | GET|HEAD monitoring/hosts/{host}/report/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Host@getReport | | |
| | GET|HEAD monitoring/hosts/{host}/thresholds/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Host@getThresholds | | |
| | GET|HEAD monitoring/hosts/{host}/timeline/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Host@getTimeline | | |
| | GET|HEAD monitoring/hosts/{host}/index/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Host@getIndex | | |
| | GET|HEAD monitoring/hosts/{host} | | Apm\Controllers\Monitoring\Hosts\Host@getIndex | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/status/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getStatus | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/details/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getDetails | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/report/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getReport | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/thresholds/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getThresholds | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/timeline/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getTimeline | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/self-healing/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getSelfHealing | | |
| | GET|HEAD monitoring/hosts/{host}/{service}/index/{one?}/{two?}/{three?}/{four?}/{five?} | | Apm\Controllers\Monitoring\Hosts\Service@getIndex | | |
| | GET|HEAD monitoring/hosts/{host}/{service} | | Apm\Controllers\Monitoring\Hosts\Service@getIndex | | |简单地说,我想摆脱{one?}/{two?}/{three?}/{four?}/{five?}部件,因为我总是可以预测参数,而且通常我希望指定必须使用的控制器并命名它们。
更新我们决定不隐式列出所有路由,因为这会使我们的routes.php非常臃肿(如果不是数千条的话,也会有数百条路由)。控制器设置就像我们现在所做的一样,除了路由器解析的额外参数外,还可以很好地工作,这在使用Route::get隐式定义路由时是不存在的。
我可能应该提到,我们稍微修改了Router类,使子资源成为可能。
发布于 2014-03-17 12:20:10
为了回答我自己的问题,我们已经为Router类做了一个覆盖。我现在知道,这也是解决这一问题的关键。
Route::controller基本上允许您将它中的所有方法隐式注册为路由的端点。正如前面提到的,这不是你通常想要做的事情,但我们在走这条路之前做了一个明智的决定。为了解决不能正确地说出哪些参数可以传递给函数的问题,他们添加了这5个“通配符”参数。我们/在问题中,我们使用类的方式使这些参数是不必要的。
我想指出的是,使用ReflectionMethod::getParameters可以使用更多的反射魔法来解决这个问题。不过,也有很多人反对使用这样的东西。
因此,简单地说,正如您可能已经猜到的那样,Laravel使用传递给Route::controller的类的反射类,并以这种方式从代码中提取路由端点。
参数被添加到类Illuminate\Routing\ControllerInspector@addUriWildcards中,因此为了防止添加这些参数,我们需要对该类进行重写。由于这个类是实例化的,然后在Illuminate\Routing\Router类中使用,所以我们还需要重写Router。
在Laravel中,您需要创建一个IoC容器来为核心类创建一个覆盖。对于Router来说,这并没有什么不同。尽管标准文档(目前)并不特别清楚如何做到这一点。
(我们实现了psr-4,并将名称空间Apm设置为app/,以便自动加载类)
在app/Lib/Routing/RoutingServiceProvider.php中
<?php namespace Apm\Lib\Routing;
use Illuminate\Routing\RoutingServiceProvider as LaravelRoutingServiceProvider;
class RoutingServiceProvider extends LaravelRoutingServiceProvider
{
protected function registerRouter()
{
$this->app['router'] = $this->app->share(function($app)
{
$router = new Router($app['events'], $app);
// If the current application environment is "testing", we will disable the
// routing filters, since they can be tested independently of the routes
// and just get in the way of our typical controller testing concerns.
if ($app['env'] == 'testing')
{
$router->disableFilters();
}
return $router;
});
}
}这将设置用于Apm\Lib\Routing\Router的路由器类,以取代Illuminate\Routing\Router。
所以在app/Lib/Routing/Router.php我们有
<?php namespace Apm\Lib\Routing;
use Illuminate\Routing\Router as LaravelRouter;
class Router extends LaravelRouter
{
/**
* Get a controller inspector instance.
*
* @return \Apm\Lib\Routing\ControllerInspector
*/
public function getInspector()
{
return $this->inspector ?: $this->inspector = new ControllerInspector;
}
}它将控制器检查器设置为Apm\Lib\Routing\ControllerInspector而不是Illuminate\Routing\ControllerInspector。
最后,在app/Lib/Routing/ControllerInspector.php中我们有:
<?php namespace Apm\Lib\Routing;
use Illuminate\Routing\ControllerInspector as LaravelControllerInspector;
class ControllerInspector extends LaravelControllerInspector
{
/**
* Add wildcards to the given URI.
*
* @param string $uri
* @return string
*/
public function addUriWildcards($uri)
{
return $uri;//.'/{one?}/{two?}/{three?}/{four?}/{five?}';
}
}然后,为了确保Laravel使用我们的类而不是它自己的类,我们需要在app/config/app.php中在'providers'数组中注册服务提供者。
'providers' => array(
'Apm\Lib\Routing\RoutingServiceProvider',
),当然,以某种方式显式地传递用于每个端点/函数方法的参数会好得多,但这就克服了隐式设置端点的问题。
如果无论如何都使用此机制,您可能希望更进一步,根据该方法接受的参数获取/使用路由参数。虽然没有添加已在被检查的控制器的基本路由模式中设置的参数。
恩芬,这解决了我们的问题,因为我们不需要参数添加到终点的路线任何地方。
发布于 2014-03-12 12:04:33
我不太熟悉处理这些额外参数的方法,但使用隐式路由并不是最佳实践,可能会导致许多问题。有关更多信息,请访问这个职位。如果您可以预测,正如您所说的,参数,我认为更好的明确定义您的路线与Route::get等。
https://stackoverflow.com/questions/22349966
复制相似问题