【问题标题】:Laravel routes confusion with slugsLaravel 路线与蛞蝓混淆
【发布时间】:2014-05-17 02:33:07
【问题描述】:

如何在 Laravel 框架中的 routes.php 中处理 2 个相似的 url?

例如:

  • mysite/shoes(分类页面)
  • mysite/adidas-model-1(产品页面)

代码:

#Categories Pages
Route::get('{catSlug}', array('uses' => 'CategoriesController@show'));

#Product Page
Route::get('{productSlug}', array('uses' => 'ProductController@show'));

如果我浏览到 mysite/shoes show 方法,CategoriesController 会被触发,但如果我浏览到 mysite/adidas-model-1,它不是 ProductController 的 show 方法,而是 CategoriesController 的一个被触发的方法。

在 routes.php 文件中是否有一个很好的方法来实现这一点?还是我将所有路由都路由到 CategoriesController@show 并且如果找不到对象触发 ProductController 的 show 方法?

谢谢。

【问题讨论】:

    标签: php url laravel slug laravel-routing


    【解决方案1】:

    在您显示的两条路线中,路由器无法知道您何时输入 catSlug 以及何时输入 productSlug - 它们都是字符串,并且没有代码区分它们。

    您可以通过添加where 子句来纠正此问题:

    Route::get('{catSlug}', array('uses' => 'CategoriesController@show'))
        ->where('catSlug', '[A-Za-z]+');
    
    Route::get('{productSlug}', array('uses' => 'ProductController@show'))
        ->where('productSlug', '[-A-Za-z0-9]+');
    

    在上面的正则表达式中,我假设类别只是由大小写字母组成的字符串 - 没有数字、空格、标点符号 - 产品包括连字符和数字。

    我还应该补充一点,这些声明的顺序很重要。产品路线也匹配品类路线,所以要先声明品类路线,这样才有机会火。否则,一切看起来都像产品。

    【讨论】:

    • 您可以将产品正则表达式更改为 '[-a-zA-Z]+-\d+$' 以使其忽略类别 slug 并仅匹配产品,只要产品以 '-NUMBER' 结尾
    【解决方案2】:

    感谢您的回答。

    我真的需要摆脱我为蛞蝓选择的东西。所以我找到了另一个解决方案。

    # Objects (cats or products)
    Route::get('{slug}', array('uses' => 'BaseController@route'));
    

    在我的 BaseController 文件中:

    public function route($slug)
    {
        // Category ?
        if($categories = Categories::where('slug', '=', $slug)->first()){  
            return View::make('site/categories/swho', compact('categories'));
        // Product ?
        }elseif($products = Products::where('slug', '=', $slug)->first()){
            return View::make('site/products/show', compact('products'));
        }
    }
    

    我首先测试一个类别对象(我的类别比产品少),如果没有找到,我就测试一个产品。

    【讨论】:

    • 我首先想在我的路由文件中创建一个前置过滤器,以保留两条路由以实现此目的,但找不到如何停止路由并告诉 Laravel“去检查下一条路由”。
    【解决方案3】:

    尽量做成这样,我就是这样用的。

    Route::get('{slug}', function($slug) {
    
     // IF IS CATEGORY...
        if($category = Category::where('slug', '=', $slug)->first()):
          return View::make('category')
            ->with('category', $category);
     // IF IS PRODUCT ...
        elseif($product = Product::where('slug', '=', $slug)->first()):
          return View::make('product')
            ->with('product', $product);
     // NOTHING? THEN ERROR
        else:
          App::abort(404);
        endif;
    });
    

    【讨论】:

      猜你喜欢
      • 2013-02-17
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 2018-11-30
      • 2015-08-27
      • 2015-10-23
      • 2019-08-15
      相关资源
      最近更新 更多