Laravel路由:如果为空则跳过参数

时间:2014-02-09 11:01:15

标签: php laravel

目前我在Laravel的路线遇到了一些问题。 例如,我有以下网址:

example.com/ads/all/experience:10-30;/wo/page-5

其中params分别是控制器,类别,滑块vars(不介意奇怪的格式,它是javascript生成的),教育水平和页面(数字)。

为使此网址正常运行,我使用以下路由:

Route::get ( 'ads/{category}/{sliders?}/{education?}/{page?}' , 'AdsController@getIndex' )
        -> where ( 'sliders?' , '(hours|experience):([0-9]+)-([0-9]+);' )
        -> where ( 'education?' , '(mbo|hbo|wo)' )
        -> where ( 'page?' , '(page-|page)([0-9])*' );

现在的问题是:我希望人们能够只输入网址的一部分。例如:

example.com/ads/all/page-5

只会显示第5页上列出的所有广告。或者:

example.com/ads/all/wo/page-3

这将显示第3页列出的所有教育级别为“wo”的广告。

我希望因为我使用参数的可选选项'?'并且由于正则表达式,laravel会在参数未满足时自动识别并且控制器会得到类似的结果:

getIndex ( $categories = 'all' , $sliders = null , $education = 'wo' , $page = '3' )

但不幸的是,事实并非如此。任何人都有任何关于如何解决此问题的想法(除了重新排序参数,这不是一个选项)

2 个答案:

答案 0 :(得分:2)

所以最终我设法让它使用这段代码。希望它也可以帮助其他人。

Route::get ( 'ads/{category}/{a?}/{b?}/{c?}' , function ( $category , $a = false , $b = false , $c = false )
{
    $params = array ( $a , $b , $c );
    $slider = $education = $page = false;

    foreach ( $params as $p )
    {
        if ( $p && preg_match ( '/(mbo|hbo|wo)/' , $p ) )
            { $education = $p; }

        elseif ( $p && preg_match ( '`^[a-zA-Z0-9+/]+={0,2}$`' , $p ) )
            { $slider = $p; }

        elseif ( $p && preg_match ( '/(page-|page)([0-9])*/' , $p ) )
            { $page = $p; }
    }

    return App::make ( 'AdsController' ) -> getIndex ( $category , $slider , $education , $page );

} );

答案 1 :(得分:0)

你的第一个理由不起作用`因为你有语法错误。

-> where ( 'sliders?' 

您应该删除那里的?。像这样:

-> where ( 'sliders' 

另一件事是,你对事物有误解。

假设我们有:

Route::get('{a?}/{b?}/{c?}', 'someController@sample');
// then your sample function have
sample($a = 'apple', $b = 'banana', $c = 'carrot')

现在,我将给出URI示例以及您应该期望的结果:

your_site/a/b/c
// $a = 'a'; $b = 'b'; $c = 'c';

your_site/a/c
// $a = 'a'; $b = 'c'

解释是,它只匹配uri上的两个参数,因此只填充函数的前两个参数。 ->where::pattern无助于改变这一点。

使用模式的使用例如是:

Route::pattern('int','[0-9]');
Route::pattern('str','[a-z]');

Route::get('ads','adsController@index');
Route::get('ads/{int?}','intController@index');
Route::get('ads/{str?}','strController@index');

your_site/ads // will use adsController@index
your_site/ads/1 // will use intController@index
you_site/ads/a // will use strController@index
you_site/ads/a1 // will produce an error

当然,您可以选择为所有三个使用1个控制器,但每个控制器使用不同的功能。这取决于你如何编程你的ctrls。

希望这清楚。

所以我建议你做一些类似我上一个例子的事情。为你想要的每个可能的param组合制定路线规则,是的......是的。