我想在laravel路由的URL模式中用连字符替换正斜杠,但是我在做这件事时遇到了麻烦!
我的路线/web.php
Route::get('/mobiles/{brand_slug}/{slug}', 'FrontendDevicesController@device')->name('device')->where(['brand_slug' => '[a-z0-9_-]+', 'slug' => '[a-z0-9_-]+']);
我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/mobile/lenovo/tab-m9但我不想这样。我的博客/移动/联想-tab-m9 ==>
所以我把路由改为:
Route::get('/mobiles/{brand_slug}-{slug}', 'FrontendDevicesController@device')->name('device')->where(['brand_slug' => '[a-z0-9_-]+', 'slug' => '[a-z0-9_-]+']);
问题是一些设备,如mysiteurl/mobile/lenovo-tab工作,而其他设备,如mysiteurl/mobile/lenovo-tab-m9不工作给我这个错误:
ErrorException
Attempt to read property "id" on null
:
->where('brand_id', $brand->id)
任何帮助我都会很感激
你的URL模式有歧义:品牌和设备都允许在它们的段符中包含连字符。
模式匹配系统一般会是"贪婪的";默认情况下,当遇到这种模糊性时,请输入"lenovo-tab-m9"最终被解读为品牌"联想"设备"m9",而不是你的意图品牌"联想"设备"标签"
在这种情况下,非贪婪匹配并没有真正的帮助——在实践中,它只意味着品牌段不能有连字符。所以你可以:
- 接受品牌段不能有连字符,使用
where(['brand_slug' => '[a-z0-9_]+', ...
- 使用其他一些不能出现在鼻涕虫中的分隔符。你可以让
{brand_slug}--{slug}
工作。