Anmerkung: Möchten Sie mehr über Routenverständnis erfahren? Werfen Sie einen Blick auf die "warum ein Framework?" Seite für eine eingehendere Erklärung.
Die grundlegende Routenführung in Flight erfolgt durch das Abgleichen eines URL-Musters mit einer Rückruffunktion oder einem Array einer Klasse und Methode.
Flight::route('/', function(){ echo 'Hallo Welt!'; });
Die Routen werden in der Reihenfolge abgeglichen, in der sie definiert sind. Die erste übereinstimmende Route für eine Anfrage wird aufgerufen.
Der Rückruffunktion kann ein beliebiges Objekt sein, das aufrufbar ist. Sie können also eine reguläre Funktion verwenden:
function hallo() { echo 'Hallo Welt!'; } Flight::route('/', 'hallo');
Sie können auch eine statische Methode einer Klasse verwenden:
class Begrüßung { public static function hallo() { echo 'Hallo Welt!'; } } Flight::route('/', [ 'Begrüßung','hallo' ]);
Oder indem Sie zuerst ein Objekt erstellen und dann die Methode aufrufen:
// Greeting.php class Begrüßung { public function __construct() { $this->name = 'Max Mustermann'; } public function hallo() { echo "Hallo, {$this->name}!"; } } // index.php $begrüßung = new Begrüßung(); Flight::route('/', [ $begrüßung, 'hallo' ]); // Sie können dies auch ohne Erstellung des Objekts zuerst tun // Anmerkung: Keine Argumente werden in den Konstruktor injiziert Flight::route('/', [ 'Begrüßung', 'hallo' ]); // Außerdem können Sie diese kürzere Syntax verwenden Flight::route('/', 'Begrüßung->hallo'); // oder Flight::route('/', Begrüßung::class.'->hallo');
Wenn Sie die Abhängigkeitsinjektion über einen Container (PSR-11, PHP-DI, Dice usw.) verwenden möchten, sind die einzigen Arten von Routen, bei denen dies verfügbar ist, entweder das direkte Erstellen des Objekts selbst und die Verwendung des Containers zum Erstellen Ihres Objekts, oder Sie können Zeichenfolgen verwenden, um die Klasse festzulegen und die aufzurufende Methode. Sie können zur Abhängigkeitsinjektion Seite gehen für weitere Informationen.
Hier ist ein schnelles Beispiel:
use flight\database\PdoWrapper; // Greeting.php class Begrüßung { protected PdoWrapper $pdoWrapper; public function __construct(PdoWrapper $pdoWrapper) { $this->pdoWrapper = $pdoWrapper; } public function hallo(int $id) { // etwas mit $this->pdoWrapper machen $name = $this->pdoWrapper->fetchField("SELECT name FROM users WHERE id = ?", [ $id ]); echo "Hallo, Welt! Mein Name ist {$name}!"; } } // index.php // Richten Sie den Container mit den erforderlichen Parametern ein // Sehen Sie sich die Abhängigkeitsinjektionsseite für weitere Informationen zu PSR-11 an $dice = new \Dice\Dice(); // Vergessen Sie nicht, die Variable mit '$dice = ' neu zuzuweisen!!!! $dice = $dice->addRule('flight\database\PdoWrapper', [ 'shared' => true, 'constructParams' => [ 'mysql:host=localhost;dbname=test', 'root', 'password' ] ]); // Registrieren Sie den Container-Handler Flight::registerContainerHandler(function($class, $params) use ($dice) { return $dice->create($class, $params); }); // Routen wie gewohnt Flight::route('/hallo/@id', [ 'Begrüßung', 'hallo' ]); // oder Flight::route('/hallo/@id', 'Begrüßung->hallo'); // oder Flight::route('/hallo/@id', 'Begrüßung::hallo'); Flight::start();
Standardmäßig werden Routenmuster mit allen Anfragemethoden abgeglichen. Sie können auf bestimmte Methoden antworten, indem Sie einen Identifikator vor der URL platzieren.
Flight::route('GET /', function () { echo 'Ich habe eine GET-Anfrage erhalten.'; }); Flight::route('POST /', function () { echo 'Ich habe eine POST-Anfrage erhalten.'; }); // Sie können Flight::get() nicht für Routen verwenden, da dies eine Methode ist, // um Variablen abzurufen, nicht um eine Route zu erstellen. // Flight::post('/', function() { /* Code */ }); // Flight::patch('/', function() { /* Code */ }); // Flight::put('/', function() { /* Code */ }); // Flight::delete('/', function() { /* Code */ });
Sie können auch mehrere Methoden auf eine einzelne Rückruffunktion abbilden, indem Sie ein |-Trennzeichen verwenden:
|
Flight::route('GET|POST /', function () { echo 'Ich habe entweder eine GET- oder eine POST-Anfrage erhalten.'; });
Zusätzlich können Sie das Router-Objekt abrufen, das einige Hilfsmethoden für Sie bereithält:
$router = Flight::router(); // alle Methoden mappen $router->map('/', function() { echo 'Hallo Welt!'; }); // GET-Anfrage $router->get('/benutzer', function() { echo 'Benutzer'; }); // $router->post(); // $router->put(); // $router->delete(); // $router->patch();
Sie können reguläre Ausdrücke in Ihren Routen verwenden:
Flight::route('/benutzer/[0-9]+', function () { // Dies passt zu /benutzer/1234 });
Obwohl diese Methode verfügbar ist, wird empfohlen, benannte Parameter oder benannte Parameter mit regulären Ausdrücken zu verwenden, da sie lesbarer und einfacher zu pflegen sind.
Sie können benannte Parameter in Ihren Routen angeben, die an Ihre Rückruffunktion übergeben werden.
Flight::route('/@name/@id', function (string $name, string $id) { echo "Hallo, $name ($id)!"; });
Sie können auch reguläre Ausdrücke mit Ihren benannten Parametern einschließen, indem Sie den :-Trennzeichen verwenden:
:
Flight::route('/@name/@id:[0-9]{3}', function (string $name, string $id) { // Dies passt zu /bob/123 // Passt aber nicht zu /bob/12345 });
Anmerkung: Das Anpassen von RegEx-Gruppen () mit benannten Parametern wird nicht unterstützt. :'(
()
Sie können benannte Parameter angeben, die optional für die Übereinstimmung sind, indem Sie Segmente in Klammern einschließen.
Flight::route( '/blog(/@year(/@month(/@day)))', function(?string $year, ?string $month, ?string $day) { // Dies passt zu den folgenden URLs: // /blog/2012/12/10 // /blog/2012/12 // /blog/2012 // /blog } );
Alle nicht übereinstimmenden optionalen Parameter werden als NULL übergeben.
NULL
Die Übereinstimmung erfolgt nur auf einzelnen URL-Segmenten. Wenn Sie mehrere übereinstimmen möchten Segmente können Sie den *-Platzhalter verwenden.
*
Flight::route('/blog/*', function () { // Dies passt zu /blog/2000/02/01 });
Um alle Anfragen an eine einzige Rückruffunktion zu routen, können Sie Folgendes tun:
Flight::route('*', function () { // Etwas machen });
Sie können die Ausführung an die nächste übereinstimmende Route weitergeben, indem Sie true aus Ihrer Rückruffunktion zurückgeben.
true
Flight::route('/benutzer/@name', function (string $name) { // Bedingung überprüfen if ($name !== "Bob") { // Zur nächsten Route fortfahren return true; } }); Flight::route('/benutzer/*', function () { // Dies wird aufgerufen });
Sie können einem Pfad einen Alias zuweisen, damit die URL später in Ihrem Code dynamisch generiert werden kann (wie in einer Vorlage beispielsweise).
Flight::route('/benutzer/@id', function($id) { echo 'benutzer:'.$id; }, false, 'benutzer_ansicht'); // später im Code an einer Stelle Flight::getUrl('benutzer_ansicht', [ 'id' => 5 ]); // gibt '/benutzer/5' zurück
Dies ist besonders hilfreich, wenn sich Ihre URL ändern sollte. Im obigen Beispiel wurde angenommen, dass die Benutzer in /admin/benutzer/@id verschoben wurden. Mit dem Alias müssen Sie nirgendwo, wo Sie den Alias referenzieren, etwas ändern, da der Alias nun /admin/benutzer/5 zurückgibt, wie im obigen Beispiel.
/admin/benutzer/@id
/admin/benutzer/5
Routenaliasierung funktioniert auch in Gruppen:
Flight::group('/benutzer', function() { Flight::route('/@id', function($id) { echo 'benutzer:'.$id; }, false, 'benutzer_ansicht'); }); // später im Code an einer Stelle Flight::getUrl('benutzer_ansicht', [ 'id' => 5 ]); // gibt '/benutzer/5' zurück
Wenn Sie die übereinstimmenden Routeninformationen untersuchen möchten, können Sie das Anfordern der Routen Objekt, das Ihrer Rückruffunktion übergeben wird, indem Sie true als dritten Parameter in die Routenmethode übergeben. Das Routenobjekt wird immer als letzten Parameter an Ihre Rückruffunktion übergeben.
Flight::route('/', function(\flight\net\Route $route) { // Array der übereinstimmenden HTTP-Methoden $route->methods; // Array der benannten Parameter $route->params; // Übereinstimmender regulärer Ausdruck $route->regex; // Enthält die Inhalte von etwaigen '*' verwendet im URL-Muster $route->splat; // Zeigt den URL-Pfad an....falls Sie ihn wirklich benötigen $route->pattern; // Zeigt an, welche Middleware dieser Route zugewiesen ist $route->middleware; // Zeigt den dem Alias zugewiesenen Alias an $route->alias; }, true);
Es gibt Zeiten, in denen Sie zusammenhängende Routen gruppieren möchten (wie /api/v1). Sie können dies durch Verwendung der group Methode tun:
/api/v1
group
Flight::group('/api/v1', function () { Flight::route('/benutzer', function () { // Passt zu /api/v1/benutzer }); Flight::route('/beiträge', function () { // Passt zu /api/v1/beiträge }); });
Sie können sogar Gruppen von Gruppen verschachteln:
Flight::group('/api', function () { Flight::group('/v1', function () { // Flight::get() holt Variablen, setzt keine Route! Siehe Objektkontext unten Flight::route('GET /benutzer', function () { // Passt zu GET /api/v1/benutzer }); Flight::post('/beiträge', function () { // Passt zu POST /api/v1/beiträge }); Flight::put('/beiträge/1', function () { // Passt zu PUT /api/v1/beiträge/1 }); }); Flight::group('/v2', function () { // Flight::get() holt Variablen, setzt keine Route! Siehe Objektkontext unten Flight::route('GET /benutzer', function () { // Passt zu GET /api/v2/benutzer }); }); });
Sie können die Routengruppierung immer noch mit dem Engine-Objekt auf folgende Weise verwenden:
Engine
$app = new \flight\Engine(); $app->group('/api/v1', function (Router $router) { // Verwenden Sie die $router Variable $router->get('/benutzer', function () { // Passt zu GET /api/v1/benutzer }); $router->post('/beiträge', function () { // Passt zu POST /api/v1/beiträge }); });
Sie können jetzt Antworten an den Client streamen, indem Sie die streamWithHeaders()-Methode verwenden. Dies ist nützlich für den Versand großer Dateien, lang laufende Prozesse oder die Generierung großer Antworten. Das Streamen einer Route wird etwas anders gehandhabt als eine normale Route.
streamWithHeaders()
Anmerkung: Das Streamen von Antworten ist nur verfügbar, wenn Sie flight.v2.output_buffering auf false gesetzt haben.
flight.v2.output_buffering
Sie können ein Antwort an den Client streamen, indem Sie die Methode stream() auf einer Route verwenden. Wenn Sie dies tun, müssen Sie alle Methoden manuell festlegen, bevor Sie etwas an den Client ausgeben. Dies erfolgt mit der header()-PHP-Funktion oder der Flight::response()->setRealHeader()-Methode.
stream()
header()
Flight::response()->setRealHeader()
Flight::route('/@dateiname', function($dateiname) { // offensichtlich würden Sie den Pfad usw. bereinigen. $dateinameSicher = basename($dateiname); // Wenn Sie hier nach Ausführung der Route zusätzliche Header setzen müssen // müssen Sie sie definieren, bevor irgendetwas für den Client ausgegeben wird. // Alle müssen ein direkter Aufruf der `header()`-Funktion oder // eines Aufrufs der `Flight::response()->setRealHeader()`-Methode sein header('Content-Disposition: attachment; filename="'.$dateinameSicher.'"'); // oder Flight::response()->setRealHeader('Content-Disposition', 'attachment; filename="'.$dateinameSicher.'"'); $dateiDaten = file_get_contents('/some/path/to/files/'.$dateinameSicher); // Fehlerbehandlung und so weiter if(empty($dateiDaten)) { Flight::halt(404, 'Datei nicht gefunden'); } // Setzen Sie die Inhaltslänge manuell, wenn Sie möchten header('Content-Length: '.filesize($dateiname)); // Streamen Sie die Daten an den Client echo $dateiDaten; // Dies ist die magische Zeile hier })->stream();
Sie können auch die streamWithHeaders()-Methode verwenden, um die Header festzulegen, bevor Sie mit dem Streamen beginnen.
Flight::route('/stream-benutzer', function() { // Sie können hier beliebige zusätzliche Header hinzufügen // Sie müssen nur `header()` oder `Flight::response()->setRealHeader()` verwenden // wie auch immer Sie Ihre Daten abrufen, nur als Beispiel... $benutzer_stmt = Flight::db()->query("SELECT id, first_name, last_name FROM users"); echo '{'; $anzahlBenutzer = count($benutzer); while($benutzer = $benutzer_stmt->fetch(PDO::FETCH_ASSOC)) { echo json_encode($benutzer); if(--$anzahlBenutzer > 0) { echo ','; } // Dies ist erforderlich, um die Daten an den Client zu senden ob_flush(); } echo '}'; // So setzen Sie die Header, bevor Sie mit dem Streaming beginnen. })->streamWithHeaders([ 'Content-Type' => 'application/json', 'Content-Disposition' => 'attachment; filename="benutzer.json"', // optionaler Statuscode, standardmäßig 200 'status' => 200 ]);