Em vez de escrever uma rota para corresponder a algo diferente de certas seqüências de caracteres estáticas, acho mais claro escrever duas rotas: uma rota para corresponder a certas seqüências estáticas e outra rota para corresponder a todo o resto.
// route that matches forbidden static strings, optionally with a postfix slug
$router->get('/{forbidden}/{optional_path?}', function () {
return response('Not found', 404);
})->where([ 'forbidden' => '(?:string1|string2)', 'optional_path' => '.*' ]);
// route that matches anything else (order of definition matters, must be last)
// might also consider using Route::fallback(), but I prefer to leave that
// alone in case my future self changes this below and opens up a hole
$router->get('/{anything?}', function () {
return response('Found', 200);
})->where([ 'anything' => '.*' ]);
O que resulta em * :
domain
=> 200 encontrado
domain/
=> 200 encontrado
domain/abc
=> 200 encontrado
domain/string1
=> 404 Não encontrado
domain/string1/
=> 404 Não encontrado
domain/string1/abc
=> 404 Não encontrado
domain/string10
=> 200 encontrado
domain/string10/
=> 200 encontrado
domain/string10/abc
=> 200 encontrado
domain/string2
=> 404 Não encontrado
domain/string2/
=> 404 Não encontrado
domain/string2/abc
=> 404 Não encontrado
domain/string20
=> 200 encontrado
domain/string20/
=> 200 encontrado
domain/string20/abc
=> 200 encontrado
Acho isso mais claro, porque não preciso pensar em termos de exclusões. Em vez disso, posso pensar em combinar exatamente o que quero proibir e deixar o Laravel reagir a todo o resto (falha na política de abertura). Isso pode não atender aos seus critérios de design, mas acredito que resulta em um código mais claro.
Além disso, o código é mais eficiente. ?!
precisa voltar atrás, o que, por definição, é mais caro que a correspondência direta.
Não tenho um ambiente Laravel à mão, mas arriscarei um palpite sobre por que suas tentativas não funcionaram. O Laravel usa o Symfony Router, que não suporta buscas em slugs . IIRC, quando uma busca é detectada, o Symfony aplica a busca a toda a URL, não à lesma à qual você vinculou o padrão. Isso mexe com a idéia do desenvolvedor de como os meta-caracteres âncoras (^, $) e gananciosos (*) funcionam. Isso pode levar a uma experiência ruim na tentativa de fazê-lo funcionar, pois o desenvolvedor opera sob uma suposição, mas as bibliotecas subjacentes operam em outra.
* Divulgação completa, escrevi isso para o Lumen e depois o converti mentalmente para o formato Laravel. É possível que haja alguns erros de tradução. Aqui está o Lumen original:
$router->get('/{forbidden:(?:string1|string2)}[/{optional_path:.*}]', function () {
return response('Not found', 404);
});
$router->get('{anything:.*}', function () {
return response('Found', 200);
});