You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel路由带额外参数:控制器接收与Blade排序链接配置咨询

Hey there! Let's take a close look at your Laravel routing and Blade setup, and go over what's working, what might be causing issues, and how to make it better.

First: Checking for Correctness

Your current setup has a couple of potential issues that might break functionality or lead to unexpected behavior:

  1. Mismatched Route Parameter & Controller Argument
    Your route defines a parameter {category-url}, but your controller method accepts $uri as the first argument. Laravel maps route parameters to controller arguments by name (automatically converting kebab-case like category-url to camelCase categoryUrl). Right now, the $uri variable in your controller won't receive the value of the category-url route parameter. You can fix this in two ways:

    • Rename the controller argument to $categoryUrl (or $category_url) to match the route parameter name (cleaner and more standard)
    • Explicitly map the parameter in your route:
      Route::get('/products/{category-url}', [CategoryController::class, 'categoryProducts'])
          ->name('client.category.products')
          ->parameters(['category-url' => 'uri']);
      
  2. Incorrect Parameter Value in Blade Route Calls
    In your Blade template, you're using Route::current()->url to pass the url parameter. This returns the full current URL (e.g., https://website.lrv/products/electronics), but your route only expects the category slug (e.g., electronics). Additionally, you're passing a key url that doesn't match the route's required parameter category-url — this will treat url as a query string parameter instead of filling the route segment. Fix this by fetching the actual route parameter and using the correct key:

    {{ route('client.category.products', [
        'category-url' => Route::current()->parameter('category-url'),
        'order' => 'article',
        'by' => 'desc'
    ]) }}
    

Optimization Recommendations

Once you fix the correctness issues, here are some ways to make this setup cleaner and more maintainable:

  1. Use Implicit Route Model Binding
    If you have a Category model with a url attribute matching the slug, let Laravel automatically fetch the category for you. This eliminates manual querying in your controller:

    // Route
    Route::get('/products/{category:url}', [CategoryController::class, 'categoryProducts'])
        ->name('client.category.products');
    
    // Controller
    public function categoryProducts(Category $category, Request $request) {
        // $category is already the matching model based on the url slug
        $products = $category->products()
            ->orderBy($request->get('order', 'created_at'), $request->get('by', 'asc'))
            ->get();
        // ... rest of your code
    }
    
  2. Simplify Sort Links in Blade
    Instead of rebuilding the route array every time, use request()->fullUrlWithQuery() to preserve existing query parameters (like filters) while updating sorting values. This is shorter and more robust:

    {{ request()->fullUrlWithQuery(['order' => 'article', 'by' => 'desc']) }}
    {{ request()->fullUrlWithQuery(['order' => 'price', 'by' => 'asc']) }}
    
  3. Centralize Sorting Logic with a Model Scope
    Avoid repeating sorting logic by adding a scope to your Product model. This also adds validation to prevent unsafe or invalid sort columns:

    // Product.php
    public function scopeSort($query, $orderBy = 'created_at', $direction = 'asc') {
        $allowedOrders = ['article', 'price', 'created_at'];
        $orderBy = in_array($orderBy, $allowedOrders) ? $orderBy : 'created_at';
        $direction = in_array($direction, ['asc', 'desc']) ? $direction : 'asc';
        
        return $query->orderBy($orderBy, $direction);
    }
    

    Then use it in your controller:

    $products = $category->products()
        ->sort($request->get('order'), $request->get('by'))
        ->get();
    
  4. Validate Request Parameters
    Add validation to your controller to ensure order and by parameters are valid, preventing unexpected behavior:

    public function categoryProducts(Category $category, Request $request) {
        $validated = $request->validate([
            'order' => 'nullable|string|in:article,price,created_at',
            'by' => 'nullable|string|in:asc,desc'
        ]);
    
        $products = $category->products()
            ->sort($validated['order'] ?? 'created_at', $validated['by'] ?? 'asc')
            ->get();
        // ...
    }
    
  5. Cache Sorted Product Lists
    If your product listings don't change frequently, cache the results to reduce database load:

    $cacheKey = "category_{$category->id}_products_{$request->get('order', 'created_at')}_{$request->get('by', 'asc')}";
    $products = Cache::remember($cacheKey, 3600, function () use ($category, $validated) {
        return $category->products()
            ->sort($validated['order'] ?? 'created_at', $validated['by'] ?? 'asc')
            ->get();
    });
    

内容的提问来源于stack exchange,提问作者Rosnowsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:29:41