首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在注册控制器路由时防止编号参数

在注册控制器路由时防止编号参数
EN

Stack Overflow用户
提问于 2014-03-12 11:23:08
回答 2查看 327关注 0票数 1

Laravel有一个很棒的路由系统,但我有一点特别困难。

在为路由定义控制器时,我希望删除创建的额外可选路由。

在Laravel 3中,您显然可以做以下工作,但从未使用过v3,我不知道这是否是我想要的,无论如何,它在v4中不起作用。

代码语言:javascript
复制
Router::$segments = 0;

例如,当我像这样定义我的路线时:

代码语言:javascript
复制
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命令中这样显示:

代码语言:javascript
复制
+--------+------------------------------------------------------------------------------------------------+------+---------------------------------------------------------+----------------+---------------+
| 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类,使子资源成为可能。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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

代码语言:javascript
复制
<?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我们有

代码语言:javascript
复制
<?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中我们有:

代码语言:javascript
复制
<?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'数组中注册服务提供者。

代码语言:javascript
复制
'providers' => array(
        'Apm\Lib\Routing\RoutingServiceProvider',
),

当然,以某种方式显式地传递用于每个端点/函数方法的参数会好得多,但这就克服了隐式设置端点的问题。

如果无论如何都使用此机制,您可能希望更进一步,根据该方法接受的参数获取/使用路由参数。虽然没有添加已在被检查的控制器的基本路由模式中设置的参数。

恩芬,这解决了我们的问题,因为我们不需要参数添加到终点的路线任何地方。

票数 1
EN

Stack Overflow用户

发布于 2014-03-12 12:04:33

我不太熟悉处理这些额外参数的方法,但使用隐式路由并不是最佳实践,可能会导致许多问题。有关更多信息,请访问这个职位。如果您可以预测,正如您所说的,参数,我认为更好的明确定义您的路线与Route::get等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22349966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档