如何在Laravel路由上删除/注册后缀?

时间:2013-07-16 16:22:43

标签: filter routes laravel

编辑:请参阅下面的我当前的问题。顶部是我之前解决的问题,但有点相关

我需要在实际到达之前修改传递给我的控制器的输入值。我正在构建一个Web应用程序,我希望能够支持多种请求输入类型(最初是JSON和XML)。我希望能够在输入到我的restful控制器之前捕获输入,并将其修改为适当的StdClass对象。

对于我的生活,我不能弄清楚如何拦截和修改输入。帮助

例如,我希望能够拥有这样的过滤器:

Route::filter('json', function()
{
    //modify input here into common PHP object format
});

Route::filter('xml', function()
{
    //modify input here into common PHP object format
});

Route::filter('other', function()
{
    //modify input here into common PHP object format
});

Route::when('*.json', 'json'); //Any route with '.json' appended uses json filter
Route::when('*.xml', 'xml'); //Any route with '.json' appended uses json filter
Route::when('*.other', 'other'); //Any route with '.json' appended uses json filter

现在我只是在我的控制器功能中进行Input::isJson()检查,然后是下面的代码 - 请注意,这有点简化了我的代码。

$data = Input::all();
$objs = array();
foreach($data as $key => $content)
{
    $objs[$key] = json_decode($content);
}

编辑:我实际上已经解决了这个问题,但现在又遇到了另一个问题。这就是我解决它的方法:

Route::filter('json', function()
{
    $new_input = array();
    if (Input::isJson())
    {
        foreach(Input::all() as $key => $content)
        {
            //Do any input modification needed here
            //Save it in $new_input
        }
        Input::replace($new_input);
    }
    else
    {
        return "Input provided was not JSON";
    }
});

Route::when('*.json', 'json'); //Any route with '.json' appended uses json filter

我现在遇到的问题是:路由器尝试在过滤器后转到的路径,包含输入URI中的.json。我见过解决此问题的唯一方法是用{/ 1>替换Input::replace($new_input)

$new_path = str_replace('.json', '', Request::path());
Redirect::to($new_path)->withInput($new_input);

然而,这导致了2个问题。首先,我无法通过POST请求重定向 - 它始终是GET请求。其次,传入的数据正在闪现在会话中 - 我宁愿通过Input类提供它,就像Input::replace()一样。

有关如何解决此问题的任何建议?

1 个答案:

答案 0 :(得分:1)

我设法解决了第二个问题 - 但它涉及了很多额外的工作并且四处寻找...我不确定它是否是最好的解决方案,但是它允许后缀路由类似于你的前缀它们。

这是我如何解决它的github提交: https://github.com/pcockwell/AuToDo/commit/dd269e756156f1e316825f4da3bfdd6930bd2e85

特别是,你应该看看:

app/config/app.php
app/lib/autodo/src/Autodo/Routing/RouteCompiler.php
app/lib/autodo/src/Autodo/Routing/Router.php
app/lib/autodo/src/Autodo/Routing/RoutingServiceProvider.php
app/routes.php
composer.json

完成这些修改后,我需要运行composer dumpautoloadphp artisan optimize。其余的这些文件只是对我的数据模型的验证以及运行这两个命令的结果。

我没有把提交分开,因为我已经工作了好几个小时而只是想要它。

我希望扩展后缀工具以允许后缀数组,以便进行任何匹配。例如,

Route::group(array('suffix' => array('.json', '.xml', 'some_other_url_suffix')), function()
{
    // Controller for base API function.
    Route::controller('api', 'ApiController');
});

理想情况下,这将接受任何匹配的呼叫

{base_url}/api/{method}{/{v1?}/{v2?}/{v3?}/{v4?}/{v5?}?}{suffix}`

其中:

  • base_url是域名网址
  • methodApiController
  • 中定义的函数
  • {/{v1?}/{v2?}/{v3?}/{v4?}/{v5?}?}是一系列最多5个可选变量,在使用Route::controller()
  • 注册控制器时添加
  • suffix是传递给Route::group()
  • 的后缀数组中的值之一

此示例尤其应该接受以下所有内容(假设localhost是基本网址,可用方法为getMethod1($str1 = null, $str2 = null)postMethod2()):

  • GET请求localhost/api/method1.json
  • GET请求localhost/api/method1.xml
  • GET请求localhost/api/method1some_other_url_suffix
  • POST请求localhost/api/method2.json
  • POST请求localhost/api/method2.xml
  • POST请求localhost/api/method2some_other_url_suffix
  • GET请求localhost/api/method1/hello/world.json
  • GET请求localhost/api/method1/hello/world.xml
  • GET请求localhost/api/method1/hello/worldsome_other_url_suffix

最后三个请求会将$str1 = 'hello'$str2 = 'world'传递给getMethod1作为参数。

编辑:允许多个后缀的更改非常简单。提交位于下方(请确保您获得BOTH提交更改以使其正常工作): https://github.com/pcockwell/AuToDo/commit/864187981a436b60868aa420f7d212aaff1d3dfe

最后,我也希望将此内容提交给laravel/framework项目。