Php 路线中间的可选参数 有没有办法在路由中间添加一个可选参数?
示例路线:Php 路线中间的可选参数 有没有办法在路由中间添加一个可选参数?,php,laravel,laravel-5,Php,Laravel,Laravel 5,示例路线: /things/entities/ /things/1/entities/ 我试过这个,但不起作用: get('things/{id?}/entities', 'MyController@doSomething'); 我知道我能做到 get('things/entities', 'MyController@doSomething'); get('things/{id}/entities', 'MyController@doSomething'); 。。。但我的问题是:我可以在路
/things/entities/
/things/1/entities/
我试过这个,但不起作用:
get('things/{id?}/entities', 'MyController@doSomething');
我知道我能做到
get('things/entities', 'MyController@doSomething');
get('things/{id}/entities', 'MyController@doSomething');
。。。但我的问题是:我可以在路由的中间添加一个可选参数吗?
不。可选参数需要走到路由的末尾,否则路由器就不知道如何将URL与路由匹配。您已经实施的是正确的方法:
get('things/entities', 'MyController@doSomething');
get('things/{id}/entities', 'MyController@doSomething');
您可以尝试使用一种路线:
get('things/{id}/entities', 'MyController@doSomething');
如果要获取所有对象的实体,请传递*或0,但我称之为hack
有一些其他的黑客可以允许你使用一条路径,但是这会增加代码的复杂性,而且它真的不值得。
在路由定义的中间有可选的参数,只有当参数存在时才会工作。考虑以下事项:- 访问路径
时,things/1/entities
参数将正确获取id
的值1
- 当访问路径
时,由于Laravel使用从左到右匹配的正则表达式,因此路径的事物/实体
部分将被视为实体
参数的值(因此在本例中id
)。这意味着路由器实际上无法匹配完整的路由,因为$id='entitites';
已匹配,并且它现在希望也有一个尾随的id
字符串(因此匹配的路由需要是/entities
,这当然不是我们要的)事物/实体/实体
但是,如果你<强>绝对< /强>需要在路由中间有一个可选的参数,那么有一个方法可以实现。这不是我推荐的解决方案,但您可以这样做:
routes/web.php
:
// Notice the missing slash
Route::get('/test/{id?}entities', 'Pages\TestController@first')
->where('id', '([0-9/]+)?')
->name('first');
Route::get('/test/entities', 'Pages\TestController@second')
->name('second');
<?php
namespace App\Http\Controllers\Pages;
use App\Http\Controllers\Controller;
class TestController extends Controller
{
public function first($id = null)
{
// If $id is not null, it will have a trailing slash
$id = rtrim($id, '/');
return 'First route with: ' . $id;
}
public function second()
{
return 'Second route';
}
}
<!-- Notice the trailing slash on id -->
<!-- Will output http://myapp.test/test/123/entities -->
<a href="{{ route('first', ['id' => '123/']) }}">
First route
</a>
<!-- Will output http://myapp.test/test/entities -->
<a href="{{ route('second') }}">
Second route
</a>
app/Http/Controllers/Pages/TestController.php
:
// Notice the missing slash
Route::get('/test/{id?}entities', 'Pages\TestController@first')
->where('id', '([0-9/]+)?')
->name('first');
Route::get('/test/entities', 'Pages\TestController@second')
->name('second');
<?php
namespace App\Http\Controllers\Pages;
use App\Http\Controllers\Controller;
class TestController extends Controller
{
public function first($id = null)
{
// If $id is not null, it will have a trailing slash
$id = rtrim($id, '/');
return 'First route with: ' . $id;
}
public function second()
{
return 'Second route';
}
}
<!-- Notice the trailing slash on id -->
<!-- Will output http://myapp.test/test/123/entities -->
<a href="{{ route('first', ['id' => '123/']) }}">
First route
</a>
<!-- Will output http://myapp.test/test/entities -->
<a href="{{ route('second') }}">
Second route
</a>
这两个链接都将触发TestController
中的first
-方法。将永远不会触发第二个方法
此解决方案适用于Laravel6.3,但不确定其他版本。再一次,这个解决方案不是好的实践