php 在laravel路由的URL模式中用连字符替换正斜杠

kqqjbcuj  于 2023-04-10  发布在  PHP
关注(0)|答案(1)|浏览(175)

我习惯于在laravel路由中用连字符替换URL模式中的正斜杠,但是我在这样做时遇到了麻烦!
my routes/web.php

Route::get('/mobiles/{brand_slug}/{slug}', 'Frontend\DevicesController@device')->name('device')->where(['brand_slug' => '[a-z0-9_-]+', 'slug' => '[a-z0-9_-]+']);

my DevicesController.php

public function device(Request $request)
    {                         

        $brand_slug = $request->brand_slug;
        $slug = $request->slug;        

        $brand = DB::table('brands')            
            ->where('slug', $brand_slug) 
            ->where('active', 1)             
            ->first();  

        $device = DB::table('devices')
            ->where('status', 'active')   
            ->where('slug', $slug) 
            ->where('brand_id', $brand->id) 
            ->first();          

        if(!$device) abort(404); 

        return view('frontend/'.$this->config->template.'/device-specs', [          
            // page variables
            'device' => $device,        
            'brand' => $brand,  

        ]);
    }

我的devices.blade.php

<div>
  <a title="{{ $device->brand_title.' '.$device->model }}" href="{{ route('device', ['brand_slug' => $device->brand_slug, 'slug' => $device->slug]) }}" class="image"><h3>{{ $device->brand_title.' '.$device->model }}</h3>
  </a>
</div>

这段代码工作正常,链接如下mysiteurl/mobiles/联想/tab-m9但我不会喜欢这个mysiteurl/mobiles/联想-tab-m9 ==〉最好的搜索引擎优化.
所以我把路由改为:

Route::get('/mobiles/{brand_slug}-{slug}', 'Frontend\DevicesController@device')->name('device')->where(['brand_slug' => '[a-z0-9_-]+', 'slug' => '[a-z0-9_-]+']);

问题是一些设备如mysiteurl/mobiles/lenovo-tab工作和其他人如mysiteurl/mobiles/lenovo-tab-m9不工作给予我这个错误:

ErrorException
Attempt to read property "id" on null

对于控制器中的此行:

->where('brand_id', $brand->id)

任何帮助我都会非常感激

lyr7nygr

lyr7nygr1#

您的URL模式不明确:商标和设备都允许在它们的块中包含连字符。
模式匹配系统在面对这种模糊性时通常会默认为“贪婪”,所以“lenovo-tab-m9”最终会被解释为品牌“lenovo-tab”、设备“m9”,而不是你想要的品牌“lenovo”、设备“tab-m9”。
在这种情况下,非贪婪匹配并没有真正的帮助-在实践中,它只是意味着品牌slug永远不能有连字符。所以你可以:

  • 接受brand slug永远不能有连字符,并使用where(['brand_slug' => '[a-z0-9_]+', ...
  • 使用其他一些不能出现在插件中的分隔符。您可能会使{brand_slug}--{slug}工作。

相关问题