【问题标题】:Laravel routing: skip parameter if emptyLaravel路由:如果为空则跳过参数
【发布时间】:2014-05-21 02:40:19
【问题描述】:

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

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

其中的参数分别是控制器、类别、滑块变量(不要介意奇怪的格式,它是 javascript 生成的)、教育程度和页面(编号)。

为了让这个 url 正常工作,我使用以下路线:

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' )

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

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    所以最终我设法让它与这段代码一起工作。希望对其他人也有帮助。

    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 );
    
    } );
    

    【讨论】:

    • 请注意,这将被视为不好的做法。拥有多个引用同一事物的 URL 有点违背 URL 的想法。并且在 SEO 方面(如果这是您考虑的),您将拥有多个内容。如果这是一个公共页面,你至少应该确保在你的头脑中设置一个<link rel="canonical"> 标记,该标记使用正确的完整 URL。
    • 感谢您指出这一点,我一定会包含规范链接。
    • 一年后我可以说这救了我的命,感谢您发布答案!
    【解决方案2】:

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

    -> 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 进行编程。

    希望这能把事情弄清楚。

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

    【讨论】:

    • 我不同意存在语法错误的事实:如果您离开 '?'出来,Laravel 实际上会抛出一个错误......此外:你的苹果和香蕉的例子:我知道这就是它的工作原理。但是,这不是我想要的工作方式。您在这里所做的是解释为什么它不起作用。关于您可能的解决方案。这有点像我为解决它所做的。
    猜你喜欢
    • 2014-12-19
    • 1970-01-01
    • 2014-12-12
    • 2013-09-22
    • 1970-01-01
    • 2020-09-09
    • 2021-06-07
    • 2018-08-20
    • 2021-12-01
    相关资源
    最近更新 更多