Anstatt eine Route zu schreiben, die mit etwas anderem als bestimmten statischen Zeichenfolgen übereinstimmt , finde ich es klarer, zwei Routen zu schreiben: eine Route, die mit bestimmten statischen Zeichenfolgen übereinstimmt, und eine andere Route, die mit allem anderen übereinstimmt.
// 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' => '.*' ]);
Was zu * führt :
domain
=> 200 gefunden
domain/
=> 200 gefunden
domain/abc
=> 200 gefunden
domain/string1
=> 404 Nicht gefunden
domain/string1/
=> 404 Nicht gefunden
domain/string1/abc
=> 404 Nicht gefunden
domain/string10
=> 200 gefunden
domain/string10/
=> 200 gefunden
domain/string10/abc
=> 200 gefunden
domain/string2
=> 404 Nicht gefunden
domain/string2/
=> 404 Nicht gefunden
domain/string2/abc
=> 404 Nicht gefunden
domain/string20
=> 200 gefunden
domain/string20/
=> 200 gefunden
domain/string20/abc
=> 200 gefunden
Ich finde das klarer, weil ich nicht in Ausschlüssen denken muss. Ich kann mir vielmehr vorstellen, genau das zu finden, was ich verbieten möchte, und dann Laravel auf alles andere reagieren zu lassen (Fail Open Policy). Dies entspricht möglicherweise nicht Ihren Entwurfskriterien, aber ich glaube, dass dies zu einem klareren Code führt.
Außerdem ist der Code leistungsfähiger. ?!
muss zurückverfolgen, was per Definition teurer ist als Forward Matching.
Ich habe keine Laravel-Umgebung zur Hand, aber ich riskiere eine Vermutung, warum Ihre Versuche nicht funktioniert haben. Laravel verwendet Symfony Router, der keine Lookarounds für Slugs unterstützt . IIRC: Wenn eine Lookaround erkannt wird, wendet Symfony die Lookaround auf die gesamte URL an, nicht auf den Slug, an den Sie das Muster gebunden haben. Dies steht im Widerspruch zu der Vorstellung des Entwicklers, wie Anker (^, $) und gierige (*) Metazeichen funktionieren. Dies kann zu einer schlechten Erfahrung beim Versuch führen, es zum Laufen zu bringen, da der Entwickler unter einer Annahme arbeitet, die zugrunde liegenden Bibliotheken jedoch unter einer anderen.
* Vollständige Offenlegung, ich habe dies für Lumen geschrieben und es dann mental in das Laravel-Format konvertiert. Möglicherweise gibt es einige Übersetzungsfehler. Hier ist das ursprüngliche Lumen:
$router->get('/{forbidden:(?:string1|string2)}[/{optional_path:.*}]', function () {
return response('Not found', 404);
});
$router->get('{anything:.*}', function () {
return response('Found', 200);
});