Flight ist ein schnelles, einfaches, erweiterbares Framework für PHP. Es ist ziemlich vielseitig und kann für den Aufbau jeder Art von Webanwendung verwendet werden. Es ist auf Einfachheit ausgelegt und so geschrieben, dass es leicht verständlich und einfach zu verwenden ist.
Hier ist ein kurzer Artikel darüber, warum Sie ein Framework verwenden sollten. Es ist eine gute Idee, die Vorteile der Verwendung eines Frameworks zu verstehen, bevor Sie eines verwenden.
Zusätzlich wurde ein ausgezeichnetes Tutorial von @lubiana erstellt. Obwohl es nicht im Detail auf Flight eingeht, wird Ihnen dieser Leitfaden helfen, einige der wichtigsten Konzepte rund um ein Framework zu verstehen und warum sie nützlich sind. Sie können das Tutorial hier finden.
Wenn Sie von einem anderen Framework wie Laravel, Slim, Fat-Free oder Symfony zu Flight migrieren, hilft Ihnen diese Seite, die Unterschiede zwischen den beiden zu verstehen.
Lernen Sie, wie Sie Ihre eigenen Klassen in Ihrer Anwendung automatisch laden.
Lernen Sie, wie Sie Routen für Ihre Webanwendung verwalten. Dies umfasst auch das Gruppieren von Routen, Routenparameter und Middleware.
Lernen Sie, wie Sie Middleware verwenden, um Anfragen und Antworten in Ihrer Anwendung zu filtern.
Lernen Sie, wie Sie Anfragen und Antworten in Ihrer Anwendung verarbeiten.
Lernen Sie, wie Sie Antworten an Ihre Benutzer senden.
Lernen Sie, wie Sie den integrierten View-Engine verwenden, um Ihre HTML-Templates zu rendern.
Lernen Sie, wie Sie Ihre Anwendung vor üblichen Sicherheitsbedrohungen schützen.
Lernen Sie, wie Sie das Framework für Ihre Anwendung konfigurieren.
Lernen Sie, wie Sie das Framework erweitern, um Ihre eigenen Methoden und Klassen hinzuzufügen.
Lernen Sie, wie Sie das Ereignissystem verwenden, um Hooks zu Ihren Methoden und internen Framework-Methoden hinzuzufügen.
Lernen Sie, wie Sie Dependency Injection Container (DIC) verwenden, um die Abhängigkeiten Ihrer Anwendung zu verwalten.
Erfahren Sie mehr über die Kernmethoden des Frameworks.
Die Abwärtskompatibilität wurde größtenteils beibehalten, aber es gibt einige Änderungen, auf die Sie achten sollten, wenn Sie von v2 auf v3 migrieren.
Es kann einige häufige Probleme geben, auf die Sie bei der Verwendung von Flight stoßen. Diese Seite unterstützt Sie bei der Problembehandlung dieser Probleme.
Sie können das Framework jederzeit durch Aufrufen der halt Methode stoppen:
halt
Flight::halt();
Sie können auch einen optionalen HTTP-Statuscode und eine Nachricht angeben:
HTTP
Flight::halt(200, 'Bin gleich wieder da...');
Das Aufrufen von halt verwirft jeglichen Antwortinhalt bis zu diesem Zeitpunkt. Wenn Sie das Framework anhalten und die aktuelle Antwort ausgeben möchten, verwenden Sie die stop Methode:
stop
Flight::stop();
Alle Fehler und Ausnahmen werden von Flight abgefangen und an die error Methode übergeben. Das Standardverhalten besteht darin, eine generische HTTP 500 Interner Serverfehler Antwort mit einigen Fehlerinformationen zu senden.
error
HTTP 500 Interner Serverfehler
Sie können dieses Verhalten nach Ihren eigenen Bedürfnissen überschreiben:
Flight::map('error', function (Throwable $error) { // Fehler behandeln echo $error->getTraceAsString(); });
Standardmäßig werden Fehler nicht im Webserver protokolliert. Sie können dies aktivieren, indem Sie die Konfiguration ändern:
Flight::set('flight.log_errors', true);
Wenn eine URL nicht gefunden werden kann, ruft Flight die notFound Methode auf. Das Standardverhalten besteht darin, eine HTTP 404 Nicht gefunden Antwort mit einer einfachen Nachricht zu senden.
notFound
HTTP 404 Nicht gefunden
Flight::map('notFound', function () { // Nicht gefunden behandeln });
Laravel ist ein Framework mit vielen Funktionen und einer erstaunlichen, auf Entwickler ausgerichteten Entwicklungsumgebung, aber auf Kosten von Leistung und Komplexität. Das Ziel von Laravel ist es, dass Entwickler auf höchstem Produktivitätsniveau arbeiten und alltägliche Aufgaben einfach erledigen können. Laravel ist eine großartige Wahl für Entwickler, die eine umfassende Enterprise-Webanwendung erstellen möchten. Dies geht jedoch mit bestimmten Kompromissen einher, insbesondere in Bezug auf Leistung und Komplexität. Die Grundlagen von Laravel zu lernen kann einfach sein, aber die Beherrschung des Frameworks kann einige Zeit in Anspruch nehmen.
Es gibt auch so viele Laravel-Module, dass Entwickler oft das Gefühl haben, dass der einzige Weg, Probleme zu lösen, darin besteht, diese Module zu nutzen, während Sie tatsächlich einfach eine andere Bibliothek verwenden oder Ihren eigenen Code schreiben könnten.
Die Abwärtskompatibilität wurde größtenteils beibehalten, aber es gibt einige Änderungen, über die Sie informiert sein sollten, wenn Sie von v2 auf v3 migrieren.
Output buffering ist der Prozess, bei dem die Ausgabe, die von einem PHP-Skript generiert wird, in einem Puffer (intern zu PHP) gespeichert wird, bevor sie an den Client gesendet wird. Dies ermöglicht es Ihnen, die Ausgabe zu ändern, bevor sie an den Client gesendet wird.
In einer MVC-Anwendung ist der Controller der "Manager" und er verwaltet, was die Ansicht tut. Das Generieren von Ausgaben außerhalb des Controllers (oder im Fall von Flights manchmal einer anonymen Funktion) bricht das MVC-Muster. Diese Änderung soll mehr im Einklang mit dem MVC-Muster stehen und das Framework vorhersehbarer und einfacher zu verwenden machen.
In v2 wurde die Ausgabepufferung auf eine Weise behandelt, bei der der eigene Ausgabepuffer nicht konsistent geschlossen wurde, was Unit-Tests und Streaming erschwert hat. Für die Mehrheit der Benutzer dürfte sich diese Änderung tatsächlich nicht auf Sie auswirken. Wenn Sie jedoch Inhalte außerhalb von Funktionsaufrufen und Controllern ausgeben (zum Beispiel in einem Hook), werden Sie wahrscheinlich Probleme haben. Das Ausgeben von Inhalten in Hooks und vor der tatsächlichen Ausführung des Frameworks hat möglicherweise in der Vergangenheit funktioniert, wird aber zukünftig nicht mehr funktionieren.
// index.php require 'vendor/autoload.php'; // Beispiel define('START_TIME', microtime(true)); function hello() { echo 'Hallo Welt'; } Flight::map('hello', 'hello'); Flight::after('hello', function(){ // Dies wird tatsächlich in Ordnung sein echo '<p>Dieser Hallo-Welt-Satz wurde Ihnen vom Buchstaben "H" präsentiert</p>'; }); Flight::before('start', function(){ // Dinge wie diese werden einen Fehler verursachen echo '<html><head><title>Meine Seite</title></head><body>'; }); Flight::route('/', function(){ // Das ist tatsächlich in Ordnung echo 'Hallo Welt'; // Dies sollte auch in Ordnung sein Flight::hello(); }); Flight::after('start', function(){ // Dies wird einen Fehler verursachen echo '<div>Ihre Seite wurde in '.(microtime(true) - START_TIME).' Sekunden geladen</div></body></html>'; });
Können Sie Ihren alten Code weiterhin so lassen, wie er ist, ohne eine Neuschreibung vorzunehmen, um ihn mit v3 zum Laufen zu bringen? Ja, das können Sie! Sie können das v2-Rendering-Verhalten aktivieren, indem Sie die Konfigurationsoption flight.v2.output_buffering auf true setzen. Dadurch können Sie weiterhin das alte Rendering-Verhalten verwenden, aber es wird empfohlen, es zukünftig zu korrigieren. In v4 des Frameworks wird dies entfernt.
flight.v2.output_buffering
true
// index.php require 'vendor/autoload.php'; Flight::set('flight.v2.output_buffering', true); Flight::before('start', function(){ // Nun wird das in Ordnung sein echo '<html><head><title>Meine Seite</title></head><body>'; }); // mehr Code
Wenn Sie bisher direkt statische Methoden für Dispatcher wie Dispatcher::invokeMethod(), Dispatcher::execute() usw. aufgerufen haben, müssen Sie Ihren Code aktualisieren, um diese Methoden nicht mehr direkt aufzurufen. Dispatcher wurde in eine mehr objektorientierte Form umgewandelt, sodass Dependency Injection Container auf eine einfachere Weise verwendet werden können. Wenn Sie eine Methode ähnlich wie Dispatcher aufrufen müssen, können Sie manuell etwas wie $result = $class->$method(...$params); oder call_user_func_array() verwenden.
Dispatcher
Dispatcher::invokeMethod()
Dispatcher::execute()
$result = $class->$method(...$params);
call_user_func_array()
halt()
stop()
redirect()
error()
Das Standardverhalten vor 3.10.0 bestand darin, sowohl die Header als auch den Antworttext zu löschen. Dies wurde geändert, um nur den Antworttext zu löschen. Wenn Sie auch die Header löschen müssen, können Sie Flight::response()->clear() verwenden.
Flight::response()->clear()
Sie können bestimmte Verhaltensweisen von Flight anpassen, indem Sie Konfigurationswerte über die set-Methode festlegen.
set
Im Folgenden finden Sie eine Liste aller verfügbaren Konfigurationseinstellungen:
?string
bool
string
Content-Length
Zusätzlich gibt es eine weitere Konfigurationseinstellung für den Loader. Dies ermöglicht Ihnen das automatische Laden von Klassen mit _ im Klassennamen.
_
// Klassenladen mit Unterstrichen aktivieren // Standardmäßig auf true gesetzt Loader::$v2ClassLoading = false;
Flight ermöglicht es Ihnen, Variablen zu speichern, damit sie überall in Ihrer Anwendung verwendet werden können.
// Speichern Sie Ihre Variable Flight::set('id', 123); // Anderswo in Ihrer Anwendung $id = Flight::get('id');
Um festzustellen, ob eine Variable festgelegt wurde, können Sie Folgendes tun:
if (Flight::has('id')) { // Etwas machen }
Sie können eine Variable löschen, indem Sie Folgendes tun:
// Löscht die id-Variable Flight::clear('id'); // Löscht alle Variablen Flight::clear();
Flight verwendet auch Variablen für Konfigurationszwecke.
Alle Fehler und Ausnahmen werden von Flight abgefangen und an die error-Methode übergeben. Das Standardverhalten besteht darin, eine allgemeine HTTP 500 Internal Server Error-Antwort mit einigen Fehlerinformationen zu senden.
HTTP 500 Internal Server Error
Sie können dieses Verhalten für Ihre eigenen Bedürfnisse überschreiben:
Wenn eine URL nicht gefunden werden kann, ruft Flight die notFound-Methode auf. Das Standardverhalten besteht darin, eine HTTP 404 Not Found-Antwort mit einer einfachen Nachricht zu senden.
HTTP 404 Not Found
Sicherheit ist ein großes Thema, wenn es um Webanwendungen geht. Sie möchten sicherstellen, dass Ihre Anwendung sicher ist und dass die Daten Ihrer Benutzer geschützt sind. Flight bietet eine Reihe von Funktionen, um Ihnen bei der Sicherung Ihrer Webanwendungen zu helfen.
HTTP-Header sind eine der einfachsten Möglichkeiten, um Ihre Webanwendungen abzusichern. Sie können Header verwenden, um Clickjacking, XSS und andere Angriffe zu verhindern. Es gibt mehrere Möglichkeiten, wie Sie diese Header zu Ihrer Anwendung hinzufügen können.
Zwei großartige Websites, um die Sicherheit Ihrer Header zu überprüfen, sind securityheaders.com und observatory.mozilla.org.
Sie können diese Header manuell hinzufügen, indem Sie die header-Methode auf dem Flight\Response-Objekt verwenden.
header
Flight\Response
// Setzen des X-Frame-Options-Headers, um Clickjacking zu verhindern Flight::response()->header('X-Frame-Options', 'SAMEORIGIN'); // Setzen des Content-Security-Policy-Headers, um XSS zu verhindern // Hinweis: Dieser Header kann sehr komplex werden, daher sollten Sie // Beispiele im Internet für Ihre Anwendung konsultieren Flight::response()->header("Content-Security-Policy", "default-src 'self'"); // Setzen des X-XSS-Protection-Headers, um XSS zu verhindern Flight::response()->header('X-XSS-Protection', '1; mode=block'); // Setzen des X-Content-Type-Options-Headers, um MIME-Sniffing zu verhindern Flight::response()->header('X-Content-Type-Options', 'nosniff'); // Setzen des Referrer-Policy-Headers, um zu steuern, wie viele Referrer-Informationen gesendet werden Flight::response()->header('Referrer-Policy', 'no-referrer-when-downgrade'); // Setzen des Strict-Transport-Security-Headers, um HTTPS zu erzwingen Flight::response()->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); // Setzen des Permissions-Policy-Headers, um zu steuern, welche Funktionen und APIs verwendet werden können Flight::response()->header('Permissions-Policy', 'geolocation=()');
Diese können am Anfang Ihrer bootstrap.php- oder index.php-Dateien hinzugefügt werden.
bootstrap.php
index.php
Sie können sie auch in einem Filter/Hook wie folgt hinzufügen:
// Header in einem Filter hinzufügen Flight::before('start', function() { Flight::response()->header('X-Frame-Options', 'SAMEORIGIN'); Flight::response()->header("Content-Security-Policy", "default-src 'self'"); Flight::response()->header('X-XSS-Protection', '1; mode=block'); Flight::response()->header('X-Content-Type-Options', 'nosniff'); Flight::response()->header('Referrer-Policy', 'no-referrer-when-downgrade'); Flight::response()->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); Flight::response()->header('Permissions-Policy', 'geolocation=()'); });
Sie können sie auch als Middleware-Klasse hinzufügen. Dies ist eine gute Möglichkeit, Ihren Code sauber und organisiert zu halten.
// app/middleware/SecurityHeadersMiddleware.php namespace app\middleware; class SecurityHeadersMiddleware { public function before(array $params): void { Flight::response()->header('X-Frame-Options', 'SAMEORIGIN'); Flight::response()->header("Content-Security-Policy", "default-src 'self'"); Flight::response()->header('X-XSS-Protection', '1; mode=block'); Flight::response()->header('X-Content-Type-Options', 'nosniff'); Flight::response()->header('Referrer-Policy', 'no-referrer-when-downgrade'); Flight::response()->header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); Flight::response()->header('Permissions-Policy', 'geolocation=()'); } } // index.php oder wo auch immer Sie Ihre Routen haben // FYI, diese leere String-Gruppe fungiert als globales Middleware für // alle Routen. Natürlich könnten Sie dasselbe tun und dies nur zu spezifischen Routen hinzufügen. Flight::group('', function(Router $router) { $router->get('/users', [ 'BenutzerController', 'getBenutzer' ]); // mehr Routen }, [ new SecurityHeadersMiddleware() ]);
Cross-Site Request Forgery (CSRF) ist eine Art von Angriff, bei dem eine bösartige Website den Browser eines Benutzers dazu bringen kann, eine Anfrage an Ihre Website zu senden. Dies kann verwendet werden, um Aktionen auf Ihrer Website ohne Wissen des Benutzers durchzuführen. Flight bietet keinen eingebauten CSRF-Schutzmechanismus, aber Sie können Ihren eigenen leicht implementieren, indem Sie Middleware verwenden.
Zunächst müssen Sie ein CSRF-Token generieren und es in der Sitzung des Benutzers speichern. Sie können dieses Token dann in Ihren Formularen verwenden und beim Absenden des Formulars überprüfen.
// Generieren eines CSRF-Tokens und Speichern in der Sitzung des Benutzers // (vorausgesetzt, Sie haben ein Sitzungsobjekt erstellt und es an Flight angehängt) // siehe die Sitzungsdokumentation für weitere Informationen Flight::register('session', \Ghostff\Session\Session::class); // Sie müssen nur ein einziges Token pro Sitzung generieren (damit es funktioniert // über mehrere Registerkarten und Anfragen für denselben Benutzer) if(Flight::session()->get('csrf_token') === null) { Flight::session()->set('csrf_token', bin2hex(random_bytes(32)) ); }
<!-- Verwenden des CSRF-Token in Ihrem Formular --> <form method="post"> <input type="hidden" name="csrf_token" value="<?= Flight::session()->get('csrf_token') ?>"> <!-- andere Formularfelder --> </form>
Sie können auch eine benutzerdefinierte Funktion festlegen, um das CSRF-Token in Ihren Latte-Vorlagen auszugeben.
// Festlegen einer benutzerdefinierten Funktion zum Ausgeben des CSRF-Tokens // Hinweis: Die Ansicht wurde mit Latte als Ansichtsmaschine konfiguriert Flight::view()->addFunction('csrf', function() { $csrfToken = Flight::session()->get('csrf_token'); return new \Latte\Runtime\Html('<input type="hidden" name="csrf_token" value="' . $csrfToken . '">'); });
Und jetzt können Sie in Ihren Latte-Vorlagen die csrf()-Funktion verwenden, um das CSRF-Token auszugeben.
csrf()
<form method="post"> {csrf()} <!-- andere Formularfelder --> </form>
Kurz und knapp, richtig?
Sie können das CSRF-Token mithilfe von Event-Filtern überprüfen:
// Dieses Middleware überprüft, ob die Anfrage eine POST-Anfrage ist, und falls ja, überprüft es, ob das CSRF-Token gültig ist Flight::before('start', function() { if(Flight::request()->method == 'POST') { // Erfassen des CSRF-Tokens aus den Formularwerten $token = Flight::request()->data->csrf_token; if($token !== Flight::session()->get('csrf_token')) { Flight::halt(403, 'Ungültiges CSRF-Token'); // oder für eine JSON-Antwort Flight::jsonHalt(['error' => 'Ungültiges CSRF-Token'], 403); } } });
Oder Sie können eine Middleware-Klasse verwenden:
// app/middleware/CsrfMiddleware.php namespace app\middleware; class CsrfMiddleware { public function before(array $params): void { if(Flight::request()->method == 'POST') { $token = Flight::request()->data->csrf_token; if($token !== Flight::session()->get('csrf_token')) { Flight::halt(403, 'Ungültiges CSRF-Token'); } } } } // index.php oder wo auch immer Sie Ihre Routen haben Flight::group('', function(Router $router) { $router->get('/users', [ 'BenutzerController', 'getBenutzer' ]); // mehr Routen }, [ new CsrfMiddleware() ]);
Cross-Site-Scripting (XSS) ist eine Art von Angriff, bei dem eine bösartige Website Code in Ihre Website einschleusen kann. Die meisten dieser Möglichkeiten ergeben sich aus Formularwerten, die Ihre Endbenutzer ausfüllen. Sie sollten niemals Ausgaben Ihrer Benutzer vertrauen! Gehen Sie immer davon aus, dass alle die besten Hacker der Welt sind. Sie können bösartiges JavaScript oder HTML in Ihre Seite einschleusen. Dieser Code kann verwendet werden, um Informationen von Ihren Benutzern zu stehlen oder Aktionen auf Ihrer Website durchzuführen. Mit der View-Klasse von Flight können Sie Ausgaben einfach escapen, um XSS-Angriffe zu verhindern.
// Nehmen wir an, der Benutzer ist clever und versucht, dies als ihren Namen zu verwenden $name = '<script>alert("XSS")</script>'; // Dies wird die Ausgabe escapen Flight::view()->set('name', $name); // Dies wird ausgegeben: <script>alert("XSS")</script> // Wenn Sie beispielsweise Latte als Ihre View-Klasse registriert haben, wird dies automatisch auch escapen. Flight::view()->render('Vorlage', ['name' => $name]);
SQL-Injection ist eine Art von Angriff, bei dem ein bösartiger Benutzer SQL-Code in Ihre Datenbank einschleusen kann. Dies kann verwendet werden, um Informationen aus Ihrer Datenbank zu stehlen oder Aktionen auf Ihrer Datenbank durchzuführen. Auch hier sollten Sie niemals Eingaben Ihrer Benutzer vertrauen! Gehen Sie immer davon aus, dass sie auf Blut aus sind. Sie können vorbereitete Anweisungen in Ihren PDO-Objekten verwenden, um SQL-Injections zu verhindern.
PDO
// Nehmen wir an, Flight::db() ist als Ihr PDO-Objekt registriert $statement = Flight::db()->prepare('SELECT * FROM users WHERE username = :username'); $statement->execute([':username' => $username]); $users = $statement->fetchAll(); // Wenn Sie die PdoWrapper-Klasse verwenden, kann dies einfach in einer Zeile erledigt werden $users = Flight::db()->fetchAll('SELECT * FROM users WHERE username = :username', [ 'username' => $username ]); // Sie können dasselbe mit einem PDO-Objekt mit ?-Platzhaltern tun $statement = Flight::db()->fetchAll('SELECT * FROM users WHERE username = ?', [ $username ]); // Versprechen Sie einfach, dass Sie niemals EVER etwas wie dies tun werden... $users = Flight::db()->fetchAll("SELECT * FROM users WHERE username = '{$username}' LIMIT 5"); // denn was ist, wenn $username = "' OR 1=1; -- "; // Nachdem die Abfrage aufgebaut ist, sieht sie so aus // SELECT * FROM users WHERE username = '' OR 1=1; -- LIMIT 5 // Es sieht seltsam aus, aber es ist eine gültige Abfrage, die funktionieren wird. Tatsächlich // ist es ein sehr verbreiteter SQL-Injectionsangriff, der alle Benutzer zurückgeben wird.
Cross-Origin Resource Sharing (CORS) ist ein Mechanismus, der es ermöglicht, dass viele Ressourcen (z. B. Schriften, JavaScript usw.) auf einer Webseite von einer anderen Domain angefordert werden können, die sich außerhalb der Domain befindet, von der die Ressource stammt. Flight hat keine integrierte Funktionalität dafür, aber dies kann leicht über ein Hook gehandhabt werden, das vor dem Aufruf der Flight::start()-Methode ausgeführt wird.
Flight::start()
// app/utils/CorsUtil.php namespace app\utils; class CorsUtil { public function set(array $params): void { $request = Flight::request(); $response = Flight::response(); if ($request->getVar('HTTP_ORIGIN') !== '') { $this->allowOrigins(); $response->header('Access-Control-Allow-Credentials', 'true'); $response->header('Access-Control-Max-Age', '86400'); } if ($request->method === 'OPTIONS') { if ($request->getVar('HTTP_ACCESS_CONTROL_REQUEST_METHOD') !== '') { $response->header( 'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD' ); } if ($request->getVar('HTTP_ACCESS_CONTROL_REQUEST_HEADERS') !== '') { $response->header( "Access-Control-Allow-Headers", $request->getVar('HTTP_ACCESS_CONTROL_REQUEST_HEADERS') ); } $response->status(200); $response->send(); exit; } } private function allowOrigins(): void { // passen Sie hier Ihre erlaubten Hosts an. $allowed = [ 'capacitor://localhost', 'ionic://localhost', 'http://localhost', 'http://localhost:4200', 'http://localhost:8080', 'http://localhost:8100', ]; $request = Flight::request(); if (in_array($request->getVar('HTTP_ORIGIN'), $allowed, true) === true) { $response = Flight::response(); $response->header("Access-Control-Allow-Origin", $request->getVar('HTTP_ORIGIN')); } } } // index.php oder wo auch immer Sie Ihre Routen haben $CorsUtil = new CorsUtil(); // Dies muss ausgeführt werden, bevor start ausgeführt wird. Flight::before('start', [ $CorsUtil, 'setupCors' ]);
Sicherheit ist wichtig und es ist wichtig sicherzustellen, dass Ihre Webanwendungen sicher sind. Flight bietet eine Reihe von Funktionen, um Ihnen bei der Sicherung Ihrer Webanwendungen zu helfen, aber es ist wichtig, immer wachsam zu sein und sicherzustellen, dass Sie alles tun, um die Daten Ihrer Benutzer sicher aufzubewahren. Gehen Sie immer vom Schlimmsten aus und vertrauen Sie niemals den Eingaben Ihrer Benutzer. Escapen Sie immer die Ausgaben und verwenden Sie vorbereitete Anweisungen, um SQL-Injection zu verhindern. Verwenden Sie immer Middleware, um Ihre Routen vor CSRF- und CORS-Angriffen zu schützen. Wenn Sie all diese Dinge tun, sind Sie auf dem besten Weg, sichere Webanwendungen zu erstellen.
Flight ermöglicht es Ihnen, seine Standardfunktionalität anzupassen, um Ihren eigenen Anforderungen gerecht zu werden, ohne dass Sie Code ändern müssen.
Zum Beispiel, wenn Flight eine URL nicht mit einer Route übereinstimmen kann, ruft es die notFound-Methode auf, die eine generische HTTP 404-Antwort sendet. Sie können dieses Verhalten überschreiben, indem Sie die map-Methode verwenden:
HTTP 404
map
Flight::map('notFound', function() { // Benutzerdefinierte 404-Seite anzeigen include 'errors/404.html'; });
Flight ermöglicht es Ihnen auch, Kernkomponenten des Frameworks zu ersetzen. Zum Beispiel können Sie die Standard-Routerklasse durch Ihre eigene benutzerdefinierte Klasse ersetzen:
// Registrieren Sie Ihre benutzerdefinierte Klasse Flight::register('router', MyRouter::class); // Wenn Flight die Router-Instanz lädt, wird Ihre Klasse geladen $myrouter = Flight::router();
Framework-Methoden wie map und register können jedoch nicht überschrieben werden. Sie erhalten einen Fehler, wenn Sie es zu versuchen.
register
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.
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.
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 ]);
Symfony ist eine Reihe von wiederverwendbaren PHP-Komponenten und ein PHP-Framework für Webprojekte.
Das Standardfundament, auf dem die besten PHP-Anwendungen aufgebaut sind. Wählen Sie eine der 50 eigenständigen Komponenten für Ihre eigenen Anwendungen aus.
Beschleunigen Sie die Erstellung und Wartung Ihrer PHP-Webanwendungen. Beenden Sie wiederholende Codieraufgaben und genießen Sie die Kontrolle über Ihren Code.
Laravel ist ein funktionsreiches Framework mit allen Extras und einem erstaunlichen, auf Entwickler ausgerichteten Ökosystem, aber zu einem Preis in Leistung und Komplexität.
Sehen Sie den Vergleich zwischen Laravel und Flight.
Slim ist ein Micro-Framework, das Flight ähnelt. Es ist darauf ausgelegt, leichtgewichtig und einfach zu bedienen zu sein, kann aber etwas komplexer sein als Flight.
Sehen Sie den Vergleich zwischen Slim und Flight.
Fat-Free ist ein Full-Stack-Framework in einem viel kleineren Paket. Obwohl es alle Werkzeuge im Werkzeugkasten hat, hat es eine Datenarchitektur, die einige Projekte komplexer machen kann, als sie sein müssen.
Sehen Sie den Vergleich zwischen Fat-Free und Flight.
Symfony ist ein modulares Enterprise-Level-Framework, das darauf ausgelegt ist, flexibel und skalierbar zu sein. Für kleinere Projekte oder neuere Entwickler kann Symfony etwas überwältigend sein.
Sehen Sie den Vergleich zwischen Symfony und Flight.
Um zu überprüfen, ob eine Variable festgelegt wurde, können Sie Folgendes tun:
if (Flight::has('id')) { // Mach etwas }
Der Dependency Injection Container (DIC) ist ein leistungsstolles Werkzeug, das es ermöglicht, die Abhängigkeiten Ihrer Anwendung zu verwalten. Es ist ein Schlüsselkonzept in modernen PHP-Frameworks und wird verwendet, um die Instanziierung und Konfiguration von Objekten zu verwalten. Einige Beispiele für DIC-Bibliotheken sind: Dice, Pimple, PHP-DI und league/container.
Ein DIC ist eine elegante Möglichkeit zu sagen, dass es Ihnen ermöglicht, Ihre Klassen an einem zentralen Ort zu erstellen und zu verwalten. Dies ist nützlich, wenn Sie dasselbe Objekt an mehrere Klassen übergeben müssen (wie Ihre Controller). Ein einfaches Beispiel könnte dies verständlicher machen.
Der alte Weg, Dinge zu erledigen, könnte so aussehen:
require 'vendor/autoload.php'; // Klasse zur Verwaltung von Benutzern aus der Datenbank class UserController { protected PDO $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } public function view(int $id) { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->execute(['id' => $id]); print_r($stmt->fetch()); } } $User = new UserController(new PDO('mysql:host=localhost;dbname=test', 'user', 'pass')); Flight::route('/user/@id', [ $UserController, 'view' ]); Flight::start();
Sie können im obigen Code sehen, dass wir ein neues PDO-Objekt erstellen und es an unsere UserController-Klasse übergeben. Dies ist in Ordnung für eine kleine Anwendung, aber wenn Ihre Anwendung wächst, werden Sie feststellen, dass Sie das gleiche PDO-Objekt an mehreren Stellen erstellen. Hier kommt ein DIC ins Spiel.
UserController
Hier ist das gleiche Beispiel unter Verwendung eines DICs (unter Verwendung von Dice):
require 'vendor/autoload.php'; // dieselbe Klasse wie oben. Nichts geändert class UserController { protected PDO $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } public function view(int $id) { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->execute(['id' => $id]); print_r($stmt->fetch()); } } // erstelle einen neuen Container $container = new \Dice\Dice; // vergiss nicht, ihn wie unten erneut zuzuweisen! $container = $container->addRule('PDO', [ // shared bedeutet, dass jedes Mal dasselbe Objekt zurückgegeben wird 'shared' => true, 'constructParams' => ['mysql:host=localhost;dbname=test', 'user', 'pass' ] ]); // Hiermit wird der Container-Handler registriert, damit Flight weiß, dass er ihn verwenden soll. Flight::registerContainerHandler(function($class, $params) use ($container) { return $container->create($class, $params); }); // jetzt können wir den Container verwenden, um unseren UserController zu erstellen Flight::route('/user/@id', [ 'UserController', 'view' ]); // oder alternativ können Sie die Route wie folgt definieren Flight::route('/user/@id', 'UserController->view'); // oder Flight::route('/user/@id', 'UserController::view'); Flight::start();
Sie denken vielleicht, dass viel zusätzlicher Code zum Beispiel hinzugefügt wurde. Die Magie entsteht, wenn Sie einen anderen Controller haben, der das PDO-Objekt benötigt.
// Wenn alle Ihre Controller einen Konstruktor haben, der ein PDO-Objekt benötigt // wird dies automatisch für jede der untenstehenden Routen eingefügt!!! Flight::route('/company/@id', 'CompanyController->view'); Flight::route('/organization/@id', 'OrganizationController->view'); Flight::route('/category/@id', 'CategoryController->view'); Flight::route('/settings', 'SettingsController->view');
Der zusätzliche Vorteil der Nutzung eines DICs besteht darin, dass Unittests wesentlich einfacher werden. Sie können ein Mock-Objekt erstellen und es an Ihre Klasse übergeben. Dies ist ein großer Vorteil, wenn Sie Tests für Ihre Anwendung schreiben!
Flight kann auch jeden PSR-11-kompatiblen Container verwenden. Dies bedeutet, dass Sie jeden Container verwenden können, der das PSR-11-Interface implementiert. Hier ist ein Beispiel für die Verwendung des PSR-11-Containers von League:
require 'vendor/autoload.php'; // dieselbe UserController-Klasse wie oben $container = new \League\Container\Container(); $container->add(UserController::class)->addArgument(PdoWrapper::class); $container->add(PdoWrapper::class) ->addArgument('mysql:host=localhost;dbname=test') ->addArgument('user') ->addArgument('pass'); Flight::registerContainerHandler($container); Flight::route('/user', [ 'UserController', 'view' ]); Flight::start();
Obwohl dies etwas ausführlicher ist als das vorherige Dice-Beispiel, erledigt es dennoch die Aufgabe mit denselben Vorteilen!
Sie können auch Ihren eigenen DIC-Handler erstellen. Dies ist nützlich, wenn Sie einen benutzerdefinierten Container haben, den Sie verwenden möchten, der nicht PSR-11 (Dice) ist. Sehen Sie sich das Grundbeispiel dafür an.
Darüber hinaus gibt es einige nützliche Standardeinstellungen, die Ihnen das Leben erleichtern, wenn Sie Flight verwenden.
Wenn Sie die Engine-Instanz in Ihren Controllern/Middleware verwenden, so konfigurieren Sie diese:
// Irgendwo in Ihrer Startdatei $engine = Flight::app(); $container = new \Dice\Dice; $container = $container->addRule('*', [ 'substitutions' => [ // Hier geben Sie die Instanz ein Engine::class => $engine ] ]); $engine->registerContainerHandler(function($class, $params) use ($container) { return $container->create($class, $params); }); // Nun können Sie die Engine-Instanz in Ihren Controllern/Middleware verwenden class MyController { public function __construct(Engine $app) { $this->app = $app; } public function index() { $this->app->render('index'); } }
Wenn Sie andere Klassen in den Container aufnehmen möchten, ist dies mit Dice einfach, da sie automatisch vom Container aufgelöst werden. Hier ist ein Beispiel:
$container = new \Dice\Dice; // Wenn Sie nichts in Ihre Klasse injizieren müssen, // müssen Sie nichts definieren! Flight::registerContainerHandler(function($class, $params) use ($container) { return $container->create($class, $params); }); class MyCustomClass { public function parseThing() { return 'thing'; } } class UserController { protected MyCustomClass $MyCustomClass; public function __construct(MyCustomClass $MyCustomClass) { $this->MyCustomClass = $MyCustomClass; } public function index() { echo $this->MyCustomClass->parseThing(); } } Flight::route('/user', 'UserController->index');
# Routen-Middleware Flight unterstützt Routen- und Gruppenrouten-Middleware. Middleware ist eine Funktion, die vor (oder nach) dem Routenrückruf ausgeführt wird. Dies ist eine großartige Möglichkeit, API-Authentifizierungsprüfungen in Ihrem Code hinzuzufügen oder zu validieren, ob der Benutzer die Berechtigung hat, auf die Route zuzugreifen. ## Grundlegende Middleware Hier ist ein grundlegendes Beispiel: ```php // Wenn Sie nur eine anonyme Funktion bereitstellen, wird sie vor dem Routenrückruf ausgeführt. Es gibt keine "nach" Middleware-Funktionen außer Klassen (siehe unten) Flight::route('/pfad', function() { echo ' Hier bin ich!'; })->addMiddleware(function() { echo 'Middleware zuerst!'; }); Flight::start(); // Dies gibt "Middleware zuerst! Hier bin ich!" aus
Es gibt einige sehr wichtige Hinweise zur Middleware, die Sie kennen sollten, bevor Sie sie verwenden:
Flight::redirect()
function($params) { ... }
public function before($params) {}
flight\Engine
__construct()
Middleware kann auch als Klasse registriert werden. Wenn Sie die "nach" Funktionalität benötigen, müssen Sie eine Klasse verwenden.
class MyMiddleware { public function before($params) { echo 'Middleware zuerst!'; } public function after($params) { echo 'Middleware zuletzt!'; } } $MyMiddleware = new MyMiddleware(); Flight::route('/pfad', function() { echo ' Hier bin ich! '; })->addMiddleware($MyMiddleware); // auch ->addMiddleware([ $MyMiddleware, $MyMiddleware2 ]); Flight::start(); // Dies zeigt "Middleware zuerst! Hier bin ich! Middleware zuletzt!" an
Angenommen, Sie haben eine Authentifizierungs-Middleware und möchten den Benutzer auf eine Login-Seite umleiten, wenn er nicht authentifiziert ist. Sie haben ein paar Optionen zur Verfügung:
Hier ist ein einfaches Beispiel mit return false;:
class MyMiddleware { public function before($params) { if (isset($_SESSION['user']) === false) { return false; } // da es true ist, geht einfach alles weiter } }
Hier ist ein Beispiel, um den Benutzer auf eine Login-Seite umzuleiten:
class MyMiddleware { public function before($params) { if (isset($_SESSION['user']) === false) { Flight::redirect('/login'); exit; } } }
Angenommen, Sie müssen einen JSON-Fehler auslösen, weil Sie eine API erstellen. Sie können das so machen:
class MyMiddleware { public function before($params) { $authorization = Flight::request()->headers['Authorization']; if(empty($authorization)) { Flight::jsonHalt(['error' => 'Sie müssen angemeldet sein, um auf diese Seite zuzugreifen.'], 403); // oder Flight::json(['error' => 'Sie müssen angemeldet sein, um auf diese Seite zuzugreifen.'], 403); exit; // oder Flight::halt(403, json_encode(['error' => 'Sie müssen angemeldet sein, um auf diese Seite zuzugreifen.']); } } }
Sie können eine Routengruppe hinzufügen, und dann wird jede Route in dieser Gruppe auch dieselbe Middleware haben. Dies ist nützlich, wenn Sie beispielsweise eine Reihe von Routen nach einer Auth-Middleware gruppieren müssen, um den API-Schlüssel im Header zu überprüfen.
// am Ende der Gruppierungsmethode hinzugefügt Flight::group('/api', function() { // Diese "leer" aussehende Route passt tatsächlich zu /api Flight::route('', function() { echo 'api'; }, false, 'api'); // Dies passt zu /api/benutzer Flight::route('/users', function() { echo 'Benutzer'; }, false, 'benutzer'); // Dies passt zu /api/benutzer/1234 Flight::route('/users/@id', function($id) { echo 'Benutzer:'.$id; }, false, 'user_ansicht'); }, [ new ApiAuthMiddleware() ]);
Wenn Sie eine globale Middleware auf alle Ihre Routen anwenden möchten, können Sie eine "leere" Gruppe hinzufügen:
// am Ende der Gruppierungsmethode Flight::group('', function() { // Dies ist immer noch /benutzer Flight::route('/users', function() { echo 'Benutzer'; }, false, 'benutzer'); // Und das ist immer noch /benutzer/1234 Flight::route('/users/@id', function($id) { echo 'Benutzer:'.$id; }, false, 'user_ansicht'); }, [ new ApiAuthMiddleware() ]);
Flight ermöglicht es Ihnen, Methoden vor und nach ihrem Aufruf zu filtern. Es gibt keine vordefinierten Hooks, die Sie sich merken müssen. Sie können beliebige der Standardframework-Methoden sowie benutzerdefinierte Methoden filtern, die Sie zugeordnet haben.
Eine Filterfunktion sieht so aus:
function (array &$params, string &$output): bool { // Filtercode }
Unter Verwendung der übergebenen Variablen können Sie die Eingabeparameter und/oder die Ausgabe manipulieren.
Sie können einen Filter vor einer Methode ausführen, indem Sie dies tun:
Flight::before('start', function (array &$params, string &$output): bool { // Etwas machen });
Sie können einen Filter nach einer Methode ausführen, indem Sie dies tun:
Flight::after('start', function (array &$params, string &$output): bool { // Etwas machen });
Sie können beliebig viele Filter zu einer Methode hinzufügen. Sie werden in der Reihenfolge aufgerufen, in der sie deklariert sind.
Hier ist ein Beispiel des Filtervorgangs:
// Eine benutzerdefinierte Methode zuordnen Flight::map('hallo', function (string $name) { return "Hallo, $name!"; }); // Einen Vorfiler hinzufügen Flight::before('hallo', function (array &$params, string &$output): bool { // Den Parameter manipulieren $params[0] = 'Fred'; return true; }); // Einen Nachfilter hinzufügen Flight::after('hallo', function (array &$params, string &$output): bool { // Die Ausgabe manipulieren $output .= " Einen schönen Tag!"; return true; }); // Die benutzerdefinierte Methode aufrufen echo Flight::hallo('Bob');
Dies sollte anzeigen:
Hallo Fred! Einen schönen Tag!
Wenn Sie mehrere Filter definiert haben, können Sie die Kette unterbrechen, indem Sie in einer Ihrer Filterfunktionen false zurückgeben:
false
Flight::before('start', function (array &$params, string &$output): bool { echo 'eins'; return true; }); Flight::before('start', function (array &$params, string &$output): bool { echo 'zwei'; // Dies wird die Kette beenden return false; }); // Dies wird nicht aufgerufen Flight::before('start', function (array &$params, string &$output): bool { echo 'drei'; return true; });
Hinweis: Kernmethoden wie map und register können nicht gefiltert werden, da sie direkt aufgerufen und nicht dynamisch aufgerufen werden.
Flight kapselt die HTTP-Anfrage in ein einzelnes Objekt, das aufgerufen werden kann durch:
$request = Flight::request();
Wenn Sie mit einer Anfrage in einer Webanwendung arbeiten, möchten Sie in der Regel einen Header, oder ein $_GET oder $_POST Parameter extrahieren, oder vielleicht sogar den rohen Anfrageinhalt. Flight bietet eine einfache Schnittstelle, um all diese Dinge zu tun.
$_GET
$_POST
Hier ist ein Beispiel, wie man einen Abfragezeichenfolgenparameter erhält:
Flight::route('/search', function(){ $keyword = Flight::request()->query['keyword']; echo "Sie suchen nach: $keyword"; // Abfrage einer Datenbank oder etwas anderem mit dem $keyword });
Hier ist ein Beispiel für ein Formular mit einer POST-Methode:
Flight::route('POST /submit', function(){ $name = Flight::request()->data['name']; $email = Flight::request()->data['email']; echo "Sie haben eingereicht: $name, $email"; // in eine Datenbank oder etwas anderes mit $name und $email speichern });
Das Anfrageobjekt bietet die folgenden Eigenschaften:
$_SERVER
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
HTTP_X_FORWARDED
HTTP_X_CLUSTER_CLIENT_IP
HTTP_FORWARDED_FOR
HTTP_FORWARDED
Sie können auf die Eigenschaften query, data, cookies und files als Arrays oder Objekte zugreifen.
query
data
cookies
files
Um einen Abfragezeichenfolgenparameter zu erhalten, können Sie tun:
$id = Flight::request()->query['id'];
Oder Sie können tun:
$id = Flight::request()->query->id;
Um den rohen HTTP-Anfrageinhalt zu erhalten, beispielsweise bei PUT-Anfragen, können Sie tun:
$body = Flight::request()->getBody();
Wenn Sie eine Anfrage mit dem Typ application/json und den Daten {"id": 123} senden, ist es über die data-Eigenschaft verfügbar:
application/json
{"id": 123}
$id = Flight::request()->data->id;
Sie können auf das $_GET-Array über die query-Eigenschaft zugreifen:
Sie können auf das $_POST-Array über die data-Eigenschaft zugreifen:
$id = Flight::request()->data['id'];
$_COOKIE
Sie können auf das $_COOKIE-Array über die cookies-Eigenschaft zugreifen:
$myCookieValue = Flight::request()->cookies['myCookieName'];
Es gibt eine Abkürzung, um auf das $_SERVER-Array über die getVar()-Methode zuzugreifen:
getVar()
$host = Flight::request()->getVar['HTTP_HOST'];
$_FILES
Sie können auf hochgeladene Dateien über die files-Eigenschaft zugreifen:
$uploadedFile = Flight::request()->files['myFile'];
Sie können Datei-Uploads mithilfe des Frameworks mit einigen Hilfsmethoden verarbeiten. Es reduziert sich im Grunde darauf, die Dateidaten aus der Anfrage zu extrahieren und sie an einen neuen Speicherort zu verschieben.
Flight::route('POST /upload', function(){ // Wenn Sie ein Eingabefeld wie <input type="file" name="myFile"> hatten $uploadedFileData = Flight::request()->getUploadedFiles(); $uploadedFile = $uploadedFileData['myFile']; $uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename()); });
Wenn Sie mehrere Dateien hochgeladen haben, können Sie sie durchlaufen:
Flight::route('POST /upload', function(){ // Wenn Sie ein Eingabefeld wie <input type="file" name="myFiles[]"> hatten $uploadedFiles = Flight::request()->getUploadedFiles()['myFiles']; foreach ($uploadedFiles as $uploadedFile) { $uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename()); } });
Sicherheitsnotiz: Validieren und sanitieren Sie immer die Benutzereingaben, insbesondere bei Datei-Uploads. Überprüfen Sie immer die Art der Dateierweiterungen, die Sie zulassen möchten, aber Sie sollten auch die "magischen Bytes" der Datei validieren, um sicherzustellen, dass es sich tatsächlich um den Dateityp handelt, den der Benutzer angibt. Es gibt Artikel und Bibliotheken, die Ihnen dabei helfen können.
Sie können auf Anfrage-Header mithilfe der getHeader()- oder getHeaders()-Methode zugreifen:
getHeader()
getHeaders()
// Vielleicht benötigen Sie den Authorization-Header $host = Flight::request()->getHeader('Authorization'); // oder $host = Flight::request()->header('Authorization'); // Wenn Sie alle Header abrufen müssen $headers = Flight::request()->getHeaders(); // oder $headers = Flight::request()->headers();
Sie können auf den rohen Anfrageinhalt über die getBody()-Methode zugreifen:
getBody()
Sie können auf die Anfrage-Methode über die method-Eigenschaft oder die getMethod()-Methode zugreifen:
method
getMethod()
$method = Flight::request()->method; // ruft tatsächlich getMethod() auf $method = Flight::request()->getMethod();
Hinweis: Die getMethod()-Methode ruft zuerst die Methode aus $_SERVER['REQUEST_METHOD'] ab, dann kann sie durch $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] überschrieben werden, wenn sie vorhanden ist, oder durch $_REQUEST['_method'], wenn sie vorhanden ist.
$_SERVER['REQUEST_METHOD']
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']
$_REQUEST['_method']
Es gibt eine Reihe von Hilfsmethoden, um Teile einer URL zu Ihrem Vorteil zusammenzufügen.
Sie können die vollständige Anforderungs-URL über die getFullUrl()-Methode abrufen:
getFullUrl()
$url = Flight::request()->getFullUrl(); // https://example.com/some/path?foo=bar
Sie können die Basis-URL über die getBaseUrl()-Methode abrufen:
getBaseUrl()
$url = Flight::request()->getBaseUrl(); // Hinweis, kein abschließender Schrägstrich. // https://example.com
Sie können eine URL an die parseQuery()-Methode übergeben, um die Abfragezeichenfolge in ein assoziatives Array zu analysieren:
parseQuery()
$query = Flight::request()->parseQuery('https://example.com/some/path?foo=bar'); // ['foo' => 'bar']
Flight wurde entwickelt, um einfach zu bedienen und zu verstehen zu sein. Im Folgenden finden Sie die vollständige Liste der Methoden für das Framework. Es besteht aus Kernmethoden, die reguläre statische Methoden sind, und erweiterbaren Methoden, die zugeordnete Methoden sind, die gefiltert oder überschrieben werden können.
Flight::map(string $name, callable $callback, bool $pass_route = false) // Erstellt eine benutzerdefinierte Framework-Methode. Flight::register(string $name, string $class, array $params = [], ?callable $callback = null) // Registriert eine Klasse bei einer Framework-Methode. Flight::before(string $name, callable $callback) // Fügt einen Filter vor einer Framework-Methode hinzu. Flight::after(string $name, callable $callback) // Fügt einen Filter nach einer Framework-Methode hinzu. Flight::path(string $path) // Fügt einen Pfad zum Laden von Klassen hinzu. Flight::get(string $key) // Ruft eine Variable ab. Flight::set(string $key, mixed $value) // Legt eine Variable fest. Flight::has(string $key) // Überprüft, ob eine Variable festgelegt ist. Flight::clear(array|string $key = []) // Löscht eine Variable. Flight::init() // Initialisiert das Framework auf die Standardeinstellungen. Flight::app() // Ruft die Anwendungsobjektinstanz ab.
Flight::start() // Startet das Framework. Flight::stop() // Stoppt das Framework und sendet eine Antwort. Flight::halt(int $code = 200, string $message = '') // Stoppt das Framework mit einem optionalen Statuscode und einer Nachricht. Flight::route(string $pattern, callable $callback, bool $pass_route = false) // Ordnet ein URL-Muster einer Rückruffunktion zu. Flight::group(string $pattern, callable $callback) // Erstellt Gruppierung für URLs, Muster muss ein String sein. Flight::redirect(string $url, int $code) // Leitet zu einer anderen URL um. Flight::render(string $file, array $data, ?string $key = null) // Rendert eine Vorlagendatei. Flight::error(Throwable $error) // Sendet eine HTTP 500-Antwort. Flight::notFound() // Sendet eine HTTP 404-Antwort. Flight::etag(string $id, string $type = 'string') // Führt ETag-HTTP-Caching durch. Flight::lastModified(int $time) // Führt HTTP-Caching für zuletzt geändert durch. Flight::json(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Sendet eine JSON-Antwort. Flight::jsonp(mixed $data, string $param = 'jsonp', int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Sendet eine JSONP-Antwort.
Alle benutzerdefinierten Methoden, die mit map und register hinzugefügt wurden, können auch gefiltert werden.
Diese Methoden sind Kernfunktionen des Frameworks und können nicht überschrieben werden.
Flight::map(string $name, callable $callback, bool $pass_route = false) // Erstellt eine benutzerdefinierte Framework-Methode. Flight::register(string $name, string $class, array $params = [], ?callable $callback = null) // Registriert eine Klasse für eine Framework-Methode. Flight::unregister(string $name) // Hebt die Registrierung einer Klasse für eine Framework-Methode auf. Flight::before(string $name, callable $callback) // Fügt einen Filter vor einer Framework-Methode hinzu. Flight::after(string $name, callable $callback) // Fügt einen Filter nach einer Framework-Methode hinzu. Flight::path(string $path) // Fügt einen Pfad für das automatische Laden von Klassen hinzu. Flight::get(string $key) // Ruft eine variable ab, die durch Flight::set() festgelegt wurde. Flight::set(string $key, mixed $value) // Legt eine Variable innerhalb des Flight-Motors fest. Flight::has(string $key) // Überprüft, ob eine Variable festgelegt ist. Flight::clear(array|string $key = []) // Löscht eine Variable. Flight::init() // Initialisiert das Framework auf seine Standardwerte. Flight::app() // Ruft die Objektinstanz der Anwendung ab Flight::request() // Ruft die Objektinstanz des Requests ab Flight::response() // Ruft die Objektinstanz der Antwort ab Flight::router() // Ruft die Objektinstanz des Routers ab Flight::view() // Ruft die Objektinstanz der Ansicht ab
Flight::start() // Startet das Framework. Flight::stop() // Stoppt das Framework und sendet eine Antwort. Flight::halt(int $code = 200, string $message = '') // Stoppt das Framework mit einem optionalen Statuscode und einer Nachricht. Flight::route(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Ordnet einem Callback ein URL-Muster zu. Flight::post(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Ordnet einem Callback ein URL-Muster für POST-Anforderungen zu. Flight::put(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Ordnet einem Callback ein URL-Muster für PUT-Anforderungen zu. Flight::patch(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Ordnet einem Callback ein URL-Muster für PATCH-Anforderungen zu. Flight::delete(string $pattern, callable $callback, bool $pass_route = false, string $alias = '') // Ordnet einem Callback ein URL-Muster für DELETE-Anforderungen zu. Flight::group(string $pattern, callable $callback) // Erstellt Gruppierungen für URLs, wobei das Muster ein String sein muss. Flight::getUrl(string $name, array $params = []) // Generiert eine URL basierend auf einem Routenalias. Flight::redirect(string $url, int $code) // Leitet zu einer anderen URL um. Flight::download(string $filePath) // Lädt eine Datei herunter. Flight::render(string $file, array $data, ?string $key = null) // Rendert eine Vorlagendatei. Flight::error(Throwable $error) // Sendet eine HTTP-500-Antwort. Flight::notFound() // Sendet eine HTTP-404-Antwort. Flight::etag(string $id, string $type = 'string') // Führt die ETag-HTTP-Cachebildung durch. Flight::lastModified(int $time) // Führt die zuletzt geänderte HTTP-Cachebildung durch. Flight::json(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Sendet eine JSON-Antwort. Flight::jsonp(mixed $data, string $param = 'jsonp', int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Sendet eine JSONP-Antwort. Flight::jsonHalt(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Sendet eine JSON-Antwort und stoppt das Framework.
Alle benutzerdefinierten Methoden, die mit map und register hinzugefügt wurden, können auch gefiltert werden. Beispiele, wie diese Methoden zugeordnet werden können, finden Sie im Flight erweitern Leitfaden.
Einige Programmierer sind vehement gegen die Verwendung von Frameworks. Sie argumentieren, dass Frameworks aufgebläht, langsam und schwer zu erlernen sind. Sie sagen, dass Frameworks unnötig sind und dass man besseren Code ohne sie schreiben kann. Es gibt sicherlich einige überzeugende Argumente gegen die Verwendung von Frameworks vorzubringen. Allerdings gibt es auch viele Vorteile bei der Verwendung von Frameworks.
Hier sind ein paar Gründe, warum Sie in Betracht ziehen sollten, ein Framework zu verwenden:
Flight ist ein Mikro-Framework. Das bedeutet, dass es klein und leichtgewichtig ist. Es bietet nicht so viele Funktionen wie größere Frameworks wie Laravel oder Symfony. Allerdings bietet es viele der Funktionen, die Sie benötigen, um Webanwendungen zu erstellen. Es ist auch einfach zu erlernen und zu verwenden. Das macht es zu einer guten Wahl, um Webanwendungen schnell und einfach zu erstellen. Wenn Sie neu in der Welt der Frameworks sind, ist Flight ein großartiges Anfänger-Framework, mit dem Sie beginnen können. Es hilft Ihnen, die Vorteile der Verwendung von Frameworks kennenzulernen, ohne Sie mit zu viel Komplexität zu überfordern. Nachdem Sie etwas Erfahrung mit Flight gesammelt haben, wird es einfacher sein, auf komplexere Frameworks wie Laravel oder Symfony umzusteigen, Flight kann jedoch immer noch eine erfolgreiche robuste Anwendung ermöglichen.
Routing ist der Kern des Flight Frameworks, aber was genau ist das? Routing ist der Prozess, bei dem eine URL genommen und mit einer bestimmten Funktion in Ihrem Code abgeglichen wird. So können Sie Ihre Website basierend auf der angeforderten URL unterschiedliche Dinge tun lassen. Zum Beispiel möchten Sie möglicherweise das Profil eines Benutzers anzeigen, wenn er /user/1234 besucht, aber eine Liste aller Benutzer anzeigen, wenn er /users besucht. All dies geschieht durch Routing.
/user/1234
/users
Es könnte etwa so funktionieren:
http://beispiel.com/user/1234
Flight::route('/user/@id', [ 'BenutzerController', 'BenutzerprofilAnzeigen' ]);
BenutzerprofilAnzeigen($id)
BenutzerController
1234
$id
BenutzerprofilAnzeigen()
Eine ordnungsgemäß zentralisierte Routerung kann tatsächlich Ihr Leben dramatisch vereinfachen! Es kann nur anfangs schwer zu erkennen sein. Hier sind ein paar Gründe:
user_view
id
/admin/user/1234
Sie sind sicherlich vertraut mit dem Script für Script-Weg, eine Website zu erstellen. Sie könnten eine Datei namens index.php haben, die eine Reihe von if-Anweisungen enthält, um die URL zu überprüfen und dann eine bestimmte Funktion auf der Grundlage der URL auszuführen. Dies ist eine Form der Routenführung, aber sie ist nicht sehr organisiert und kann schnell außer Kontrolle geraten. Flights Routensystem ist eine viel organisiertere und leistungsfähigere Art, die Routenführung zu handhaben.
if
Dies hier?
// /user/view_profile.php?id=1234 if ($_GET['id']) { $id = $_GET['id']; viewUserProfile($id); } // /user/edit_profile.php?id=1234 if ($_GET['id']) { $id = $_GET['id']; editUserProfile($id); } // etc...
Oder das hier?
// index.php Flight::route('/user/@id', [ 'BenutzerController', 'BenutzerprofilAnzeigen' ]); Flight::route('/user/@id/edit', [ 'BenutzerController', 'BenutzerprofilBearbeiten' ]); // Vielleicht in Ihrem app/controllers/UserController.php class UserController { public function viewUserProfile($id) { // Mach etwas } public function editUserProfile($id) { // Mach etwas } }
Hoffentlich erkennen Sie langsam die Vorteile der Verwendung eines zentralisierten Routingsystems. Es ist viel einfacher zu verwalten und zu verstehen auf lange Sicht!
Flight bietet eine einfache und unkomplizierte Möglichkeit, Anfragen und Antworten zu bearbeiten. Dies ist der Kern dessen, was ein Web-Framework macht. Es nimmt eine Anfrage von einem Benutzerbrowser entgegen, verarbeitet sie und sendet dann eine Antwort zurück. So können Sie Webanwendungen erstellen, die Dinge wie das Anzeigen eines Benutzerprofils, das Einloggen eines Benutzers oder das Posten eines neuen Blogposts ermöglichen.
Eine Anfrage ist das, was der Browser eines Benutzers an Ihren Server sendet, wenn er Ihre Website besucht. Diese Anfrage enthält Informationen darüber, was der Benutzer tun möchte. Zum Beispiel könnte sie Informationen darüber enthalten, welche URL der Benutzer besuchen möchte, welche Daten der Benutzer an Ihren Server senden möchte oder welche Art von Daten der Benutzer von Ihrem Server erhalten möchte. Es ist wichtig zu wissen, dass eine Anfrage schreibgeschützt ist. Sie können die Anfrage nicht ändern, aber Sie können daraus lesen.
Flight bietet eine einfache Möglichkeit, Informationen zur Anfrage abzurufen. Sie können über die Methode Flight::request() Informationen zur Anfrage abrufen. Diese Methode gibt ein Request-Objekt zurück, das Informationen zur Anfrage enthält. Mit diesem Objekt können Sie Informationen zur Anfrage abrufen, wie die URL, die Methode oder die Daten, die der Benutzer an Ihren Server gesendet hat.
Flight::request()
Request
Eine Antwort ist das, was Ihr Server an den Browser eines Benutzers zurücksendet, wenn er Ihre Website besucht. Diese Antwort enthält Informationen darüber, was Ihr Server tun möchte. Zum Beispiel könnte es Informationen darüber enthalten, welche Art von Daten Ihr Server an den Benutzer senden möchte, welche Art von Daten Ihr Server von dem Benutzer erhalten möchte oder welche Art von Daten Ihr Server auf dem Computer des Benutzers speichern möchte.
Flight bietet eine einfache Möglichkeit, eine Antwort an den Browser eines Benutzers zu senden. Sie können eine Antwort mit der Methode Flight::response() senden. Diese Methode nimmt ein Response-Objekt als Argument und sendet die Antwort an den Browser des Benutzers. Sie können dieses Objekt verwenden, um eine Antwort an den Browser des Benutzers zu senden, wie z. B. HTML, JSON oder eine Datei. Flight hilft Ihnen dabei, einige Teile der Antwort automatisch zu generieren, um die Dinge zu vereinfachen, aber letztendlich haben Sie die Kontrolle darüber, was Sie dem Benutzer zurücksenden.
Flight::response()
Response
Flight stellt eine eingebaute Unterstützung für das Caching auf HTTP-Ebene bereit. Wenn die Cache-Bedingung erfüllt ist, wird Flight eine HTTP 304 Not Modified-Antwort zurückgeben. Das nächste Mal, wenn der Client die gleiche Ressource anfordert, wird er aufgefordert, die lokal zwischengespeicherte Version zu verwenden.
304 Not Modified
Sie können die lastModified-Methode verwenden und einen UNIX-Zeitstempel übergeben, um das Datum und die Uhrzeit festzulegen, wann eine Seite zuletzt geändert wurde. Der Client wird weiterhin seinen Cache verwenden, bis der zuletzt geänderte Wert geändert wird.
lastModified
Flight::route('/nachrichten', function () { Flight::lastModified(1234567890); echo 'Dieser Inhalt wird zwischengespeichert sein.'; });
Das Caching von ETag ist ähnlich wie Last-Modified, außer dass Sie eine beliebige ID für die Ressource angeben können:
ETag
Last-Modified
Flight::route('/nachrichten', function () { Flight::etag('meine-eindeutige-id'); echo 'Dieser Inhalt wird zwischengespeichert sein.'; });
Denken Sie daran, dass das Aufrufen von lastModified oder etag sowohl den Cache-Wert setzen als auch überprüfen wird. Wenn der Cache-Wert zwischen den Anfragen identisch ist, sendet Flight sofort eine HTTP 304-Antwort und stoppt die Verarbeitung.
etag
HTTP 304
Flight hilft dabei, einen Teil der Antwortheader für Sie zu generieren, aber Sie haben die meiste Kontrolle darüber, was Sie dem Benutzer zurückschicken. Manchmal können Sie direkt auf das Response-Objekt zugreifen, aber die meiste Zeit verwenden Sie die Flight-Instanz, um eine Antwort zu senden.
Flight
Flight verwendet ob_start(), um die Ausgabe zu puffern. Das bedeutet, dass Sie echo oder print verwenden können, um dem Benutzer eine Antwort zu senden und Flight wird dies erfassen und mit den entsprechenden Headern an den Benutzer zurücksenden.
echo
print
// Dies sendet "Hallo, Welt!" an den Browser des Benutzers Flight::route('/', function() { echo "Hallo, Welt!"; }); // HTTP/1.1 200 OK // Content-Type: text/html // // Hallo, Welt!
Alternativ können Sie die write()-Methode aufrufen, um den Body ebenfalls hinzuzufügen.
write()
// Dies sendet "Hallo, Welt!" an den Browser des Benutzers Flight::route('/', function() { // ausführlicher, aber erledigt manchmal den Job, wenn Sie es brauchen Flight::response()->write("Hallo, Welt!"); // wenn Sie den Body, den Sie zu diesem Zeitpunkt festgelegt haben, abrufen möchten // können Sie dies wie folgt tun $body = Flight::response()->getBody(); });
Sie können den Statuscode der Antwort durch Verwendung der status-Methode festlegen:
status
Flight::route('/@id', function($id) { if($id == 123) { Flight::response()->status(200); echo "Hallo, Welt!"; } else { Flight::response()->status(403); echo "Verboten"; } });
Wenn Sie den aktuellen Statuscode abrufen möchten, können Sie die status-Methode ohne Argumente verwenden:
Flight::response()->status(); // 200
Sie können den Antwortbody durch Verwendung der write-Methode festlegen, jedoch wird, wenn Sie etwas mit echo ausgeben, dies erfasst und als Antwortbody über Output-Pufferung gesendet.
write
Flight::route('/', function() { Flight::response()->write("Hallo, Welt!"); }); // dasselbe wie Flight::route('/', function() { echo "Hallo, Welt!"; });
Wenn Sie den Antwortbody löschen möchten, können Sie die clearBody-Methode verwenden:
clearBody
Flight::route('/', function() { if($someCondition) { Flight::response()->write("Hallo, Welt!"); } else { Flight::response()->clearBody(); } });
Sie können einen Callback auf dem Antwortbody ausführen, indem Sie die addResponseBodyCallback-Methode verwenden:
addResponseBodyCallback
Flight::route('/benutzer', function() { $db = Flight::db(); $users = $db->fetchAll("WÄHLE * AUS benutzer"); Flight::render('benutzertabelle', ['benutzer' => $benutzer]); }); // Dies wird alle Antworten für eine Route komprimieren Flight::response()->addResponseBodyCallback(function($body) { return gzencode($body, 9); });
Sie können mehrere Callbacks hinzufügen, und sie werden in der Reihenfolge ausgeführt, in der sie hinzugefügt wurden. Da dies jeden aufrufbar akzeptieren kann, kann es ein Klassenarray [ $klasse, 'methode' ], eine Closure $strReplace = function($body) { str_replace('hi', 'there', $body); }; oder ein Funktionsname 'minify' akzeptieren, wenn Sie beispielsweise eine Funktion haben, um Ihren HTML-Code zu verkleinern.
[ $klasse, 'methode' ]
$strReplace = function($body) { str_replace('hi', 'there', $body); };
'minify'
Hinweis: Routen-Callbacks funktionieren nicht, wenn Sie die Konfigurationsoption flight.v2.output_buffering verwenden.
Wenn Sie möchten, dass dies nur für eine bestimmte Route gilt, können Sie den Callback direkt in der Route hinzufügen:
Flight::route('/benutzer', function() { $db = Flight::db(); $users = $db->fetchAll("WÄHLE * AUS benutzer"); Flight::render('benutzertabelle', ['benutzer' => $benutzer]); // Dies wird nur die Antwort für diese Route komprimieren Flight::response()->addResponseBodyCallback(function($body) { return gzencode($body, 9); }); });
Sie können auch Middleware verwenden, um den Callback über Middleware auf alle Routen anzuwenden:
// MinifyMiddleware.php class MinifyMiddleware { public function before() { // wenden Sie den Callback hier auf das response() Objekt an. Flight::response()->addResponseBodyCallback(function($body) { return $this->minify($body); }); } protected function minify(string $body): string { // den Body irgendwie verkleinern return $body; } } // index.php Flight::group('/benutzer', function() { Flight::route('', function() { /* ... */ }); Flight::route('/@id', function($id) { /* ... */ }); }, [ new MinifyMiddleware() ]);
Sie können einen Header wie den Inhaltsprototyp der Antwort durch Verwendung der header-Methode festlegen:
// Dies sendet "Hallo, Welt!" im Klartext an den Browser des Benutzers Flight::route('/', function() { Flight::response()->header('Content-Type', 'text/plain'); // oder Flight::response()->setHeader('Content-Type', 'text/plain'); echo "Hallo, Welt!"; });
Flight bietet Unterstützung zum Senden von JSON- und JSONP-Antworten. Um eine JSON-Antwort zu senden, übergeben Sie einige Daten, die JSON-codiert werden sollen:
Flight::json(['id' => 123]);
Sie können auch als zweites Argument einen Statuscode übergeben:
Flight::json(['id' => 123], 201);
Sie können auch ein Argument in der letzten Position übergeben, um die Formatierung zu aktivieren:
Flight::json(['id' => 123], 200, true, 'utf-8', JSON_PRETTY_PRINT);
Wenn Sie Optionen, die an Flight::json() übergeben werden, ändern und eine einfachere Syntax wünschen, können Sie die JSON-Methode einfach neu zuordnen:
Flight::json()
Flight::map('json', function($daten, $code = 200, $optionen = 0) { Flight::_json($daten, $code, true, 'utf-8', $optionen); } // Und jetzt kann es so verwendet werden Flight::json(['id' => 123], 200, JSON_PRETTY_PRINT);
Wenn Sie eine JSON-Antwort senden und die Ausführung stoppen möchten, können Sie die jsonHalt-Methode verwenden. Dies ist nützlich für Fälle, in denen Sie möglicherweise eine Art Autorisierung überprüfen und wenn der Benutzer nicht autorisiert ist, können Sie sofort eine JSON-Antwort senden, den aktuellen Body löschen Inhalt und Anhalten der Ausführung.
jsonHalt
Flight::route('/benutzer', function() { $authorisiert = someAuthorizationCheck(); // Überprüfen, ob der Benutzer autorisiert ist if($authorisiert === false) { Flight::jsonHalt(['Fehler' => 'Nicht autorisiert'], 401); } // Fortfahren mit dem Rest der Route });
Vor v3.10.0 müssten Sie etwas ähnliches tun:
Flight::route('/benutzer', function() { $authorisiert = someAuthorizationCheck(); // Überprüfen, ob der Benutzer autorisiert ist if($authorisiert === false) { Flight::halt(401, json_encode(['Fehler' => 'Nicht autorisiert'])); } // Fortfahren mit dem Rest der Route });
Für JSONP-Anfragen können Sie optional den Abfrageparameter, den Sie verwenden, um Ihre Rückruffunktion zu definieren, übergeben:
Flight::jsonp(['id' => 123], 'q');
So erhalten Sie beim Senden einer GET-Anfrage mit ?q=my_func die Ausgabe:
?q=my_func
my_func({"id":123});
Wenn Sie keinen Abfrageparameter angeben, wird standardmäßig jsonp verwendet.
jsonp
Sie können die aktuelle Anfrage durch Verwendung der redirect()-Methode und Angabe einer neuen URL umleiten:
Flight::redirect('/neuer/ort');
Standardmäßig sendet Flight einen HTTP-Statuscode 303 ("Siehe Andere"). Sie können optional auch einen benutzerdefinierten Code festlegen:
Flight::redirect('/neuer/ort', 401);
Sie können das Framework jederzeit anhalten, indem Sie die halt-Methode aufrufen:
Sie können auch optional einen HTTP-Statuscode und eine Nachricht angeben:
Flight::halt(200, 'Bin gleich zurück...');
Das Aufrufen von halt verwirft jeglichen Antwortinhalt bis zu diesem Zeitpunkt. Wenn Sie das Framework anhalten und den aktuellen Antwortinhalt ausgeben möchten, verwenden Sie die stop-Methode:
Sie können den Antwortbody und Header löschen, indem Sie die clear()-Methode verwenden. Dadurch werden alle Header der Antwort zugewiesen, der Antwortbody gelöscht und der Statuscode auf 200 gesetzt.
clear()
200
Flight::response()->clear();
Wenn Sie nur den Antwortbody löschen möchten, können Sie die clearBody()-Methode verwenden:
clearBody()
// Dies behält weiterhin alle Header bei, die für das response() Objekt festgelegt wurden. Flight::response()->clearBody();
Flight bietet eine integrierte Unterstützung für das Caching auf HTTP-Ebene. Wenn die Cachebedingung erfüllt ist, gibt Flight eine HTTP 304 Not Modified-Antwort zurück. Wenn der Client das nächste Mal die gleiche Ressource anfordert, wird er aufgefordert, seine lokal zwischengespeicherte Version zu verwenden.
Wenn Sie Ihre gesamte Antwort zwischenspeichern möchten, können Sie die cache()-Methode verwenden und die Zeit zum Zwischenspeichern angeben.
cache()
// Dies zwischenspeichert die Antwort für 5 Minuten Flight::route('/nachrichten', function () { Flight::response()->cache(time() + 300); echo 'Dieser Inhalt wird zwischengespeichert.'; }); // Alternativ können Sie einen String verwenden, den Sie an die strtotime() Methode übergeben würden Flight::route('/nachrichten', function () { Flight::response()->cache('+5 minutes'); echo 'Dieser Inhalt wird zwischengespeichert.'; });
Sie können die lastModified-Methode verwenden und einen UNIX-Zeitstempel übergeben, um das Datum festzulegen und Uhrzeit, zu der eine Seite zuletzt geändert wurde. Der Client wird weiterhin seinen Cache verwenden, bis der zuletzt geänderte Wert geändert wird.
Flight::route('/nachrichten', function () { Flight::lastModified(1234567890); echo 'Dieser Inhalt wird zwischengespeichert.'; });
ETag-Caching ist ähnlich wie Last-Modified, außer dass Sie eine beliebige ID für die Ressource festlegen können:
Flight::route('/nachrichten', function () { Flight::etag('meine-eindeutige-id'); echo 'Dieser Inhalt wird zwischengespeichert.'; });
Bitte beachten Sie, dass das Aufrufen von lastModified oder etag sowohl den Cache-Wert setzen als auch überprüfen wird. Wenn der Cache-Wert zwischen den Anfragen gleich ist, sendet Flight sofort eine HTTP 304-Antwort und stoppt die Verarbeitung.
Es gibt eine Hilfsmethode zum Herunterladen einer Datei. Sie können die download-Methode und den Dateipfad verwenden.
download
Flight::route('/download', function () { Flight::download('/pfad/zur/datei.txt'); });
Anstatt Flight als globale statische Klasse auszuführen, können Sie es optional als ein Objektinstanz ausführen.
require 'flight/autoload.php'; $app = Flight::app(); $app->route('/', function () { echo 'Hallo Welt!'; }); $app->start();
Also würden Sie anstelle des Aufrufs der statischen Methode die Instanzmethode mit demselben Namen am Engine-Objekt aufrufen.
Sie können die aktuelle Anfrage umleiten, indem Sie die redirect Methode verwenden und eine neue URL übergeben:
redirect
Flight::redirect('/neuer/standort');
Standardmäßig sendet Flight einen HTTP-Statuscode 303. Sie können optional einen benutzerdefinierten Code setzen:
Flight::redirect('/neuer/standort', 401);
Flight bietet standardmäßig einige grundlegende Template-Funktionalitäten. Um ein Ansichts-Template anzuzeigen, rufen Sie die Methode render mit dem Namen der Template-Datei und optionalen Template-Daten auf:
render
Flight::render('hello.php', ['name' => 'Bob']);
Die übergebenen Template-Daten werden automatisch in das Template eingefügt und können wie eine lokale Variable referenziert werden. Template-Dateien sind einfach PHP-Dateien. Wenn der Inhalt der hello.php Template-Datei lautet:
hello.php
Hallo, <?= $name ?>!
Die Ausgabe wäre:
Hallo, Bob!
Sie können auch manuell Ansichtsvariablen festlegen, indem Sie die Methode set verwenden:
Flight::view()->set('name', 'Bob');
Die Variable name ist nun in allen Ihren Ansichten verfügbar. Sie können also einfach Folgendes tun:
name
Flight::render('hello');
Beachten Sie, dass beim Festlegen des Namens des Templates in der Render-Methode die Dateierweiterung .php ausgelassen werden kann.
.php
Standardmäßig sucht Flight nach einem views-Verzeichnis für Template-Dateien. Sie können einen alternativen Pfad für Ihre Templates festlegen, indem Sie die folgende Konfiguration setzen:
views
Flight::set('flight.views.path', '/pfad/zu/ansichten');
Es ist üblich, dass Websites eine einzelne Layout-Template-Datei mit sich änderndem Inhalt haben. Um Inhalte zu rendern, die in einem Layout verwendet werden sollen, können Sie einen optionalen Parameter an die render-Methode übergeben.
Flight::render('header', ['heading' => 'Hallo'], 'headerContent'); Flight::render('body', ['body' => 'Welt'], 'bodyContent');
Ihre Ansicht wird dann gespeicherte Variablen namens headerContent und bodyContent haben. Sie können dann Ihr Layout rendern, indem Sie Folgendes tun:
headerContent
bodyContent
Flight::render('layout', ['title' => 'Startseite']);
Wenn die Template-Dateien wie folgt aussehen:
header.php:
header.php
<h1><?= $heading ?></h1>
body.php:
body.php
<div><?= $body ?></div>
layout.php:
layout.php
<html> <head> <title><?= $title ?></title> </head> <body> <?= $headerContent ?> <?= $bodyContent ?> </body> </html>
<html> <head> <title>Startseite</title> </head> <body> <h1>Hallo</h1> <div>Welt</div> </body> </html>
Flight ermöglicht es Ihnen, den Standard-View-Engine einfach durch Registrieren Ihrer eigenen View-Klasse auszutauschen. So verwenden Sie z. B. den Smarty Template-Engine für Ihre Ansichten:
// Smarty-Bibliothek laden require './Smarty/libs/Smarty.class.php'; // Registrieren Sie Smarty als View-Klasse // Geben Sie auch eine Rückruffunktion zum Konfigurieren von Smarty beim Laden an Flight::register('view', Smarty::class, [], function (Smarty $smarty) { $smarty->setTemplateDir('./templates/'); $smarty->setCompileDir('./templates_c/'); $smarty->setConfigDir('./config/'); $smarty->setCacheDir('./cache/'); }); // Template-Daten zuweisen Flight::view()->assign('name', 'Bob'); // Template anzeigen Flight::view()->display('hello.tpl');
Zu Ihrer Information sollten Sie auch die Standard-Rendermethode von Flight überschreiben:
Flight::map('render', function(string $template, array $data): void { Flight::view()->assign($data); Flight::view()->display($template); });
Flight bietet standardmäßig einige grundlegende Vorlagenfunktionalitäten.
Wenn Sie komplexere Vorlagenanforderungen haben, beachten Sie die Smarty- und Latte-Beispiele im Abschnitt Benutzerdefinierte Ansichten.
Um eine Ansichtsvorlage anzuzeigen, rufen Sie die Methode render mit dem Namen der Vorlagendatei und optionalen Vorlagendaten auf:
Die von Ihnen übergebenen Vorlagendaten werden automatisch in die Vorlage eingefügt und können wie eine lokale Variable referenziert werden. Vorlagendateien sind einfach PHP-Dateien. Wenn der Inhalt der hello.php-Vorlagendatei folgendermaßen aussieht:
Die Variable name steht nun in allen Ihren Ansichten zur Verfügung. Sie können also einfach Folgendes tun:
Beachten Sie, dass Sie bei der Angabe des Namens der Vorlage in der render-Methode die .php-Erweiterung weglassen können.
Standardmäßig sucht Flight nach einem views-Verzeichnis für Vorlagendateien. Sie können einen alternativen Pfad für Ihre Vorlagen festlegen, indem Sie die folgende Konfiguration festlegen:
Flight::set('flight.views.path', '/pfad/zur/vorlagen');
Es ist üblich, dass Websites eine einzelne Layoutvorlagendatei mit austauschbarem Inhalt haben. Um Inhalt zu rendern, der in einem Layout verwendet werden soll, können Sie einen optionalen Parameter an die render-Methode übergeben.
Wenn die Vorlagendateien wie folgt aussehen:
Flight ermöglicht es Ihnen, die Standardansichtsmaschine einfach durch Registrierung Ihrer eigenen Ansichtsklasse auszutauschen.
So verwenden Sie den Smarty Vorlagenmotor für Ihre Ansichten:
// Smarty-Bibliothek laden require './Smarty/libs/Smarty.class.php'; // Registrieren Sie Smarty als Ansichtsklasse // Übergeben Sie auch eine Rückruffunktion, um Smarty beim Laden zu konfigurieren Flight::register('view', Smarty::class, [], function (Smarty $smarty) { $smarty->setTemplateDir('./templates/'); $smarty->setCompileDir('./templates_c/'); $smarty->setConfigDir('./config/'); $smarty->setCacheDir('./cache/'); }); // Vorlagendaten zuweisen Flight::view()->assign('name', 'Bob'); // Vorlage anzeigen Flight::view()->display('hello.tpl');
Zu Vollständigkeit sollten Sie auch die Standard-render-Methode von Flight überschreiben:
So verwenden Sie den Latte Vorlagenmotor für Ihre Ansichten:
// Registrieren Sie Latte als Ansichtsklasse // Übergeben Sie auch eine Rückruffunktion, um Latte beim Laden zu konfigurieren Flight::register('view', Latte\Engine::class, [], function (Latte\Engine $latte) { // Hier wird Latte Ihre Vorlagen zwischenspeichern, um die Dinge zu beschleunigen. // Ein schöner Aspekt an Latte ist, dass es Ihren Cache automatisch aktualisiert, // wenn Sie Änderungen an Ihren Vorlagen vornehmen! $latte->setTempDirectory(__DIR__ . '/../cache/'); // Teilen Sie Latte mit, in welchem Stammverzeichnis sich Ihre Ansichten befinden werden. $latte->setLoader(new \Latte\Loaders\FileLoader(__DIR__ . '/../views/')); }); // Und verpacken Sie es, damit Sie Flight::render() korrekt verwenden können Flight::map('render', function(string $template, array $data): void { // Dies entspricht $latte_engine->render($template, $data); echo Flight::view()->render($template, $data); });
Fat-Free (zärtlich bekannt als F3) ist ein leistungsstarkes und dennoch einfach zu bedienendes PHP-Mikro-Framework, das entwickelt wurde, um Ihnen zu helfen, dynamische und robuste Webanwendungen schnell zu erstellen!
Flight vergleicht sich in vielerlei Hinsicht mit Fat-Free und ist wahrscheinlich der engste Verwandte in Bezug auf Funktionen und Einfachheit. Fat-Free hat viele Funktionen, die Flight nicht hat, aber auch viele Funktionen, die Flight besitzt. Fat-Free beginnt, sein Alter zu zeigen und ist nicht mehr so beliebt wie früher.
Aktualisierungen werden seltener und die Community ist nicht mehr so aktiv wie zuvor. Der Code ist einfach genug, aber manchmal kann der Mangel an Syntaxdisziplin das Lesen und Verstehen erschweren. Es funktioniert für PHP 8.3, aber der Code selbst sieht immer noch aus, als würde er in PHP 5.3 existieren.
GET
DB\SQL
active-record
Cache
beforeroute
afterroute
HIVE
Flight ist so konzipiert, dass es sich um ein erweiterbares Framework handelt. Das Framework wird mit einer Reihe von Standardmethoden und -komponenten geliefert, jedoch können Sie Ihre eigenen Methoden zuordnen, Ihre eigenen Klassen registrieren oder sogar bestehende Klassen und Methoden überschreiben.
Wenn Sie auf der Suche nach einem DIC (Dependency Injection Container) sind, wechseln Sie zur Dependency Injection Container Seite.
Um Ihre eigene einfache benutzerdefinierte Methode zuzuordnen, verwenden Sie die map Funktion:
// Ordnen Sie Ihre Methode zu Flight::map('hello', function (string $name) { echo "hallo $name!"; }); // Rufen Sie Ihre benutzerdefinierte Methode auf Flight::hello('Bob');
Obwohl es möglich ist, einfache benutzerdefinierte Methoden zu erstellen, wird empfohlen, einfach Standardfunktionen in PHP zu erstellen. Diese haben eine Autovervollständigung in IDEs und sind einfacher zu lesen. Das Äquivalent des obigen Codes wäre:
function hello(string $name) { echo "hallo $name!"; } hello('Bob');
Dies wird eher verwendet, wenn Sie Variablen in Ihre Methode übergeben müssen, um einen erwarteten Wert zu erhalten. Die Verwendung der register() Methode wie unten gezeigt dient mehr dazu, Konfigurationsdaten zu übergeben und dann Ihre vorab konfigurierte Klasse aufzurufen.
register()
Um Ihre eigene Klasse zu registrieren und zu konfigurieren, verwenden Sie die register Funktion:
// Registrieren Sie Ihre Klasse Flight::register('user', User::class); // Erhalten Sie eine Instanz Ihrer Klasse $user = Flight::user();
Die Registriermethode ermöglicht es Ihnen auch, Parameter an den Konstruktor Ihrer Klasse zu übergeben. Wenn Sie Ihre benutzerdefinierte Klasse laden, wird sie vorinitialisiert. Sie können die Konstruktorparameter definieren, indem Sie ein zusätzliches Array übergeben. Hier ist ein Beispiel zum Laden einer Datenbankverbindung:
// Klasse mit Konstruktorparametern registrieren Flight::register('db', PDO::class, ['mysql:host=localhost;dbname=test', 'benutzer', 'passwort']); // Erhalten Sie eine Instanz Ihrer Klasse // Dies erstellt ein Objekt mit den definierten Parametern // // new PDO('mysql:host=localhost;dbname=test','benutzer','passwort'); // $db = Flight::db(); // und wenn Sie es später im Code benötigen, rufen Sie einfach die gleiche Methode erneut auf class SomeController { public function __construct() { $this->db = Flight::db(); } }
Wenn Sie einen zusätzlichen Rückrufparameter übergeben, wird er unmittelbar nach der Klassenkonstruktion ausgeführt. Dies ermöglicht es Ihnen, alle Einrichtungsvorgänge für Ihr neues Objekt durchzuführen. Die Rückruffunktion erhält einen Parameter, eine Instanz des neuen Objekts.
// Der Rückruf erhält das konstruierte Objekt Flight::register( 'db', PDO::class, ['mysql:host=localhost;dbname=test', 'benutzer', 'passwort'], function (PDO $db) { $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } );
Standardmäßig erhalten Sie jedes Mal, wenn Sie Ihre Klasse laden, eine gemeinsam genutzte Instanz. Um eine neue Instanz einer Klasse zu erhalten, geben Sie einfach false als Parameter ein:
// Gemeinsam genutzte Instanz der Klasse $gemeinsam = Flight::db(); // Neue Instanz der Klasse $neu = Flight::db(false);
Bitte beachten Sie, dass zugeordnete Methoden Vorrang vor registrierten Klassen haben. Wenn Sie beide unter demselben Namen deklarieren, wird nur die zugeordnete Methode aufgerufen.
Flight ermöglicht es Ihnen, seine Standardfunktionalität anzupassen, um Ihren eigenen Anforderungen gerecht zu werden, ohne dass Sie Code ändern müssen. Sie können alle Methoden, die Sie überschreiben können, hier einsehen.
Wenn Flight beispielsweise einer URL keine Route zuordnen kann, ruft es die notFound Methode auf, die eine generische HTTP 404-Antwort sendet. Sie können dieses Verhalten überschreiben, indem Sie die map Methode verwenden:
Flight ermöglicht es auch, Kernkomponenten des Frameworks zu ersetzen. Sie können beispielsweise die Standard-Routerklasse durch Ihre eigene benutzerdefinierte Klasse ersetzen:
// Registrieren Sie Ihre benutzerdefinierte Klasse Flight::register('router', MeineRouter::class); // Wenn Flight die Router-Instanz lädt, wird Ihre Klasse geladen $meinerouter = Flight::router();
Framework-Methoden wie map und register können jedoch nicht überschrieben werden. Sie erhalten einen Fehler, wenn Sie dies versuchen.
# JSON Flight bietet Unterstützung für das Senden von JSON- und JSONP-Antworten. Um eine JSON-Antwort zu senden, übergeben Sie einige Daten, die in JSON kodiert werden sollen: ```php Flight::json(['id' => 123]);
Für JSONP-Anfragen können Sie optional den Abfrage-Parameter Namen angeben, den Sie verwenden, um Ihre Rückruffunktion zu definieren:
Wenn Sie also eine GET-Anfrage mit ?q=my_func stellen, sollten Sie die Ausgabe erhalten:
Wenn Sie keinen Abfrageparameter Namen angeben, wird standardmäßig jsonp verwendet.
Slim ist ein PHP-Mikrorahmenwerk, das Ihnen hilft, schnell einfache, aber leistungsstarke Webanwendungen und APIs zu erstellen.
Eine Menge der Inspiration für einige der v3-Funktionen von Flug kam tatsächlich von Schlank. Das Gruppieren von Routen und das Ausführen von Middleware in einer bestimmten Reihenfolge sind zwei Funktionen, die von Schlank inspiriert wurden. Schlank v3 wurde mit Blick auf Einfachheit entwickelt, aber es gab gemischte Bewertungen bezüglich v4.
Autoloading ist ein Konzept in PHP, bei dem Sie ein Verzeichnis oder Verzeichnisse angeben, aus denen Klassen geladen werden sollen. Dies ist weitaus vorteilhafter als die Verwendung von require oder include, um Klassen zu laden. Es ist auch eine Voraussetzung für die Verwendung von Composer-Paketen.
require
include
Standardmäßig wird jede Flight-Klasse automatisch dank Composer geladen. Wenn Sie jedoch Ihre eigenen Klassen automatisch laden möchten, können Sie die Flight::path()-Methode verwenden, um ein Verzeichnis zum Laden von Klassen anzugeben.
Flight::path()
Angenommen, wir haben einen Verzeichnisbaum wie folgt:
# Beispiel-Pfad /home/user/project/my-flight-project/ ├── app │ ├── cache │ ├── config │ ├── controllers - enthält die Controller für dieses Projekt │ ├── translations │ ├── UTILS - enthält Klassen nur für diese Anwendung (dies ist alles großgeschrieben, um später ein Beispiel zu geben) │ └── views └── public └── css └── js └── index.php
Sie haben möglicherweise festgestellt, dass dies die gleiche Dateistruktur wie diese Dokumentationsseite ist.
Sie können jedes Verzeichnis wie folgt zum Laden angeben:
/** * public/index.php */ // Fügen Sie einen Pfad zum Autoloader hinzu Flight::path(__DIR__.'/../app/controllers/'); Flight::path(__DIR__.'/../app/utils/'); /** * app/controllers/MyController.php */ // keine Namensräume erforderlich // Alle automatisch geladenen Klassen sollten Pascal-Fall sein (jedes Wort großgeschrieben, keine Leerzeichen) // Ab Version 3.7.2 können Sie Pascal_Snake_Case für Ihre Klassennamen verwenden, indem Sie Loader::setV2ClassLoading(false); ausführen; class MyController { public function index() { // etwas machen } }
Wenn Sie Namensräume haben, wird es tatsächlich sehr einfach, dies zu implementieren. Verwenden Sie die Flight::path()-Methode, um das Stammverzeichnis (nicht das Dokumentenstammverzeichnis oder den public/-Ordner) Ihrer Anwendung anzugeben.
public/
/** * public/index.php */ // Fügen Sie einen Pfad zum Autoloader hinzu Flight::path(__DIR__.'/../');
So könnte Ihr Controller aussehen. Schauen Sie sich das folgende Beispiel an, aber achten Sie auf die Kommentare für wichtige Informationen.
/** * app/controllers/MyController.php */ // Namensräume sind erforderlich // Namensräume entsprechen der Verzeichnisstruktur // Namensräume müssen der gleichen Groß- und Kleinschreibung wie die Verzeichnisstruktur folgen // Namensräume und Verzeichnisse dürfen keine Unterstriche enthalten (sofern Loader::setV2ClassLoading(false) nicht festgelegt ist) namespace app\controllers; // Alle automatisch geladenen Klassen sollten Pascal-Fall sein (jedes Wort großgeschrieben, keine Leerzeichen) // Ab Version 3.7.2 können Sie Pascal_Snake_Case für Ihre Klassennamen verwenden, indem Sie Loader::setV2ClassLoading(false); ausführen; class MyController { public function index() { // etwas machen } }
Und wenn Sie eine Klasse in Ihrem "utils"-Verzeichnis automatisch laden möchten, würden Sie im Grunde dasselbe tun:
/** * app/UTILS/ArrayHelperUtil.php */ // Der Namensraum muss der Verzeichnisstruktur und Groß- und Kleinschreibung entsprechen (beachten Sie, dass das UTILS-Verzeichnis alle großgeschrieben ist // wie im obigen Dateibaum) namespace app\UTILS; class ArrayHelperUtil { public function changeArrayCase(array $array) { // etwas machen } }
Ab Version 3.7.2 können Sie Pascal_Snake_Case für Ihre Klassennamen verwenden, indem Sie Loader::setV2ClassLoading(false); ausführen. Dadurch können Sie Unterstriche in Ihren Klassennamen verwenden. Dies wird nicht empfohlen, steht aber für diejenigen zur Verfügung, die es benötigen.
Loader::setV2ClassLoading(false);
/** * public/index.php */ // Fügen Sie einen Pfad zum Autoloader hinzu Flight::path(__DIR__.'/../app/controllers/'); Flight::path(__DIR__.'/../app/utils/'); Loader::setV2ClassLoading(false); /** * app/controllers/My_Controller.php */ // keine Namensräume erforderlich class My_Controller { public function index() { // etwas machen } }
Diese Seite hilft Ihnen bei der Fehlerbehebung von häufig auftretenden Problemen, auf die Sie bei der Verwendung von Flight stoßen könnten.
Wenn Sie einen 404-Nicht gefunden Fehler sehen (aber Sie schwören, dass er wirklich da ist und es sich nicht um einen Tippfehler handelt), könnte dies tatsächlich ein Problem sein, wenn Sie einen Wert in Ihrem Routen-Endpunkt zurückgeben, anstatt ihn einfach auszugeben. Der Grund dafür ist beabsichtigt, könnte aber einige Entwickler überraschen.
Flight::route('/hallo', function(){ // Dies könnte einen 404 Nicht gefunden Fehler verursachen return 'Hallo Welt'; }); // Was Sie wahrscheinlich wollen Flight::route('/hallo', function(){ echo 'Hallo Welt'; });
Der Grund dafür liegt in einem speziellen Mechanismus, der in den Router eingebaut ist und die Rückgabewerte als Anweisung für "zur nächsten Route gehen" behandelt. Das Verhalten ist im Routing Abschnitt dokumentiert.
Dafür könnte es einige Gründe geben, warum dies nicht passiert. Unten sind einige Beispiele aufgeführt, aber stellen Sie sicher, dass Sie auch den Autoloading Abschnitt überprüfen.
Am häufigsten ist, dass der Klassenname nicht mit dem Dateinamen übereinstimmt.
Wenn Sie eine Klasse namens MeineKlasse haben, sollte die Datei MeineKlasse.php genannt werden. Wenn Sie eine Klasse namens MeineKlasse haben und die Datei meineklasse.php genannt wird, kann der Autoloader sie nicht finden.
MeineKlasse
MeineKlasse.php
meineklasse.php
Wenn Sie Namespaces verwenden, sollte der Namespace mit der Verzeichnisstruktur übereinstimmen.
// Code // Wenn Ihr MyController im app/controllers Verzeichnis ist und benannt ist // dann funktioniert dies nicht. Flight::route('/hallo', 'MeinController->hallo'); // Sie müssen eine dieser Optionen auswählen Flight::route('/hallo', 'app\controllers\MeinController->hallo'); // oder wenn Sie eine Verwendungserklärung oben haben use app\controllers\MeinController; Flight::route('/hallo', [ MeinController::class, 'hallo' ]); // kann auch geschrieben werden Flight::route('/hallo', MeinController::class.'->hallo'); // auch... Flight::route('/hallo', [ 'app\controllers\MeinController', 'hallo' ]);
path()
Im Skelett-App ist dies im config.php File definiert, aber damit Ihre Klassen gefunden werden, müssen Sie sicherstellen, dass die path() Methode definiert ist (wahrscheinlich zum Stammverzeichnis Ihres Verzeichnisses), bevor Sie versuchen, sie zu verwenden.
config.php
// Fügen Sie einen Pfad zum Autoloader hinzu Flight::path(__DIR__.'/../');
Wenn Sie Composer verwenden, können Sie den folgenden Befehl ausführen:
composer require flightphp/core
ODER Sie können die Dateien herunterladen direkt und sie in Ihr Webverzeichnis extrahieren.
Für Apache bearbeiten Sie Ihre .htaccess-Datei wie folgt:
.htaccess
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [QSA,L]
Hinweis: Wenn Sie Flight in einem Unterverzeichnis verwenden müssen, fügen Sie die Zeile hinzu RewriteBase /subdir/ direkt nach RewriteEngine On hinzu. Hinweis: Wenn Sie alle Serverdateien schützen möchten, wie z.B. eine db- oder env-Datei. Fügen Sie dies Ihrer .htaccess-Datei hinzu:
Hinweis: Wenn Sie Flight in einem Unterverzeichnis verwenden müssen, fügen Sie die Zeile hinzu RewriteBase /subdir/ direkt nach RewriteEngine On hinzu.
RewriteBase /subdir/
RewriteEngine On
Hinweis: Wenn Sie alle Serverdateien schützen möchten, wie z.B. eine db- oder env-Datei. Fügen Sie dies Ihrer .htaccess-Datei hinzu:
RewriteEngine On RewriteRule ^(.*)$ index.php
Für Nginx fügen Sie Folgendes zu Ihrer Serverdeklaration hinzu:
server { location / { try_files $uri $uri/ /index.php; } }
<?php // Wenn Sie Composer verwenden, fordern Sie den Autoloader an. require 'vendor/autoload.php'; // wenn Sie Composer nicht verwenden, laden Sie das Framework direkt // require 'flight/Flight.php'; // Definieren Sie dann eine Route und weisen Sie eine Funktion zu, um die Anfrage zu bearbeiten. Flight::route('/', function () { echo 'Hallo Welt!'; }); // Starten Sie schließlich das Framework. Flight::start();
Urheberrecht © 2024 @mikecao, @n0nag0n
2024
@mikecao, @n0nag0n
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der zugehörigen Dokumentationsdateien (die "Software") erhält, die Erlaubnis erteilt, uneingeschränkt mit der Software zu handeln, einschließlich und ohne Einschränkung der Rechte zur Nutzung, Veränderung, Zusammenführung, Veröffentlichung, Verbreitung, Unterlizenzierung und/oder Verkauf von Kopien der Software, und Personen, denen die Software überlassen wird, zu gestatten, dies zu tun, unter den folgenden Bedingungen:
Der obige Urheberrechtsvermerk und dieser Genehmigungsvermerk sind in allen Kopien oder wesentlichen Teilen der Software enthalten.
DIE SOFTWARE WIRD "WIE BESEHEN" BEREITGESTELLT, OHNE JEGLICHE GARANTIE, AUSDRÜCKLICH ODER IMPLIZIERT, EINSCHLIEßLICH DER GARANTIE DER MARKTFÄHIGKEIT, DER EIGNUNG FÜR EINEN BESTIMMTEN ZWECK UND DER NICHTVERLETZUNG. IN KEINEM FALL HAFTEN DIE AUTOREN ODER COPYRIGHT-INHABER FÜR ANSPRÜCHE, SCHÄDEN ODER ANDERE HAFTUNGEN, OB IN EINER VERTRAGS- ODER DELIKTSKLAGE, DIE AUS ODER IN VERBINDUNG MIT DER SOFTWARE ODER DER VERWENDUNG ODER ANDEREN GESCHÄFTEN MIT DER SOFTWARE ENTSTEHEN.
Flight ist ein schnelles, einfaches, erweiterbares Framework für PHP. Es ist ziemlich vielseitig und kann für den Aufbau aller Arten von Webanwendungen verwendet werden. Es ist mit Einfachheit im Sinn entwickelt und auf eine Art und Weise geschrieben, die einfach zu verstehen und zu nutzen ist.
Flight ist ein großartiges Einsteiger-Framework für diejenigen, die neu in PHP sind und lernen möchten, wie man Webanwendungen erstellt. Es ist auch ein großartiges Framework für erfahrene Entwickler, die mehr Kontrolle über ihre Webanwendungen haben möchten. Es ist konzipiert, um leicht eine RESTful API, eine einfache Webanwendung oder eine komplexe Webanwendung zu erstellen.
<?php // wenn mit Composer installiert require 'vendor/autoload.php'; // oder wenn manuell per Zip-Datei installiert // require 'flight/Flight.php'; Flight::route('/', function() { echo 'Hallo Welt!'; }); Flight::route('/json', function() { Flight::json(['hallo' => 'Welt']); }); Flight::start();
Einfach genug, oder? Erfahren Sie mehr über Flight in der Dokumentation!
Es gibt eine Beispielanwendung, die Ihnen hilft, mit dem Flight Framework zu beginnen. Gehen Sie zu flightphp/skeleton, um Anweisungen zum Einstieg zu erhalten! Sie können auch die Beispiele Seite besuchen, um sich von einigen der Dinge inspirieren zu lassen, die Sie mit Flight machen können.
Wir sind im Matrix-Chat mit uns unter #flight-php-framework:matrix.org.
Es gibt zwei Möglichkeiten, wie Sie zu Flight beitragen können:
Flight erfordert PHP 7.4 oder höher.
Hinweis: PHP 7.4 wird unterstützt, da zum aktuellen Zeitpunkt der Erstellung (2024) PHP 7.4 die Standardversion für einige LTS-Linux-Distributionen ist. Ein Wechsel zu PHP >8 würde für diese Benutzer viele Kopfschmerzen verursachen. Das Framework unterstützt auch PHP >8.
Flight wird unter der MIT Lizenz veröffentlicht.
overclokk/cookie ist eine einfache Bibliothek zum Verwalten von Cookies in Ihrer App.
Die Installation ist mit Composer einfach.
composer require overclokk/cookie
Die Verwendung ist so einfach wie das Registrieren einer neuen Methode in der Flight-Klasse.
use Overclokk\Cookie\Cookie; /* * Setzen Sie dies in Ihrer Bootstrap- oder public/index.php-Datei */ Flight::register('cookie', Cookie::class); /** * ExampleController.php */ class ExampleController { public function login() { // Setze ein Cookie // Sie möchten, dass dies falsch ist, damit Sie eine neue Instanz erhalten // verwenden Sie den folgenden Kommentar, wenn Sie eine Autovervollständigung wünschen /** @var \Overclokk\Cookie\Cookie $cookie */ $cookie = Flight::cookie(false); $cookie->set( 'stay_logged_in', // Name des Cookies '1', // der Wert, den Sie setzen möchten 86400, // Anzahl der Sekunden, die das Cookie dauern soll '/', // Pfad, auf dem das Cookie verfügbar sein wird 'example.com', // Domain, auf der das Cookie verfügbar sein wird true, // das Cookie wird nur über eine sichere HTTPS-Verbindung übertragen true // das Cookie ist nur über das HTTP-Protokoll verfügbar ); // optional, wenn Sie die Standardwerte beibehalten und eine schnelle Möglichkeit haben möchten, ein Cookie lange zu setzen $cookie->forever('stay_logged_in', '1'); } public function home() { // Überprüfen Sie, ob Sie das Cookie haben if (Flight::cookie()->has('stay_logged_in')) { // bringe sie z.B. in den Dashboard-Bereich. Flight::redirect('/dashboard'); } } }
defuse/php-encryption ist eine Bibliothek, die zum Verschlüsseln und Entschlüsseln von Daten verwendet werden kann. Das Einrichten und Starten ist ziemlich einfach, um mit der Verschlüsselung und Entschlüsselung von Daten zu beginnen. Sie haben ein großartiges Tutorial, das dabei hilft, die Grundlagen zur Verwendung der Bibliothek sowie wichtige Sicherheitsaspekte in Bezug auf Verschlüsselung zu erklären.
Die Installation ist einfach mit Composer.
composer require defuse/php-encryption
Dann müssen Sie einen Verschlüsselungsschlüssel generieren.
vendor/bin/generate-defuse-key
Das wird einen Schlüssel ausgeben, den Sie sicher aufbewahren müssen. Sie könnten den Schlüssel in Ihrer app/config/config.php-Datei im Array am Ende der Datei aufbewahren. Auch wenn es nicht der perfekte Ort ist, ist es zumindest etwas.
app/config/config.php
Nun, da Sie die Bibliothek und einen Verschlüsselungsschlüssel haben, können Sie damit beginnen, Daten zu verschlüsseln und zu entschlüsseln.
use Defuse\Crypto\Crypto; use Defuse\Crypto\Key; /* * In Ihrer Bootstrap- oder public/index.php-Datei festlegen */ // Verschlüsselungsmethode Flight::map('encrypt', function($rohdaten) { $verschlüsselungsschlüssel = /* $config['encryption_key'] oder ein file_get_contents davon, wo Sie den Schlüssel platziert haben */; return Crypto::encrypt($rohdaten, Key::loadFromAsciiSafeString($verschlüsselungsschlüssel)); }); // Entschlüsselungsmethode Flight::map('decrypt', function($verschlüsselte_daten) { $verschlüsselungsschlüssel = /* $config['encryption_key'] oder ein file_get_contents davon, wo Sie den Schlüssel platziert haben */; try { $rohdaten = Crypto::decrypt($verschlüsselte_daten, Key::loadFromAsciiSafeString($verschlüsselungsschlüssel)); } catch (Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException $ex) { // Ein Angriff! Entweder der falsche Schlüssel wurde geladen oder der Geheimtext hat sich seit seiner Erstellung geändert -- entweder in der Datenbank korrupt oder absichtlich von Eve modifiziert, um einen Angriff durchzuführen. // ... diesen Fall auf eine Art und Weise behandeln, die für Ihre Anwendung geeignet ist ... } return $rohdaten; }); Flight::route('/encrypt', function() { $verschlüsselte_daten = Flight::encrypt('Das ist ein Geheimnis'); echo $verschlüsselte_daten; }); Flight::route('/decrypt', function() { $verschlüsselte_daten = '...'; // Verschlüsselte Daten von irgendwoher erhalten $entschlüsselte_daten = Flight::decrypt($verschlüsselte_daten); echo $entschlüsselte_daten; });
Leichte, einfache und eigenständige PHP-In-File-Caching-Klasse
Vorteile
Klicken Sie hier, um den Code anzuzeigen.
Installation über Composer:
composer require wruczek/php-file-cache
Die Verwendung ist ziemlich einfach.
use Wruczek\PhpFileCache\PhpFileCache; $app = Flight::app(); // Sie geben das Verzeichnis, in dem der Cache gespeichert wird, dem Konstruktor weiter $app->register('cache', PhpFileCache::class, [ __DIR__ . '/../cache/' ], function(PhpFileCache $cache) { // Dies stellt sicher, dass der Cache nur verwendet wird, wenn sich die Anwendung im Produktionsmodus befindet // ENVIRONMENT ist eine Konstante, die in Ihrer Bootstrap-Datei oder anderswo in Ihrer Anwendung festgelegt ist $cache->setDevMode(ENVIRONMENT === 'development'); });
Dann können Sie es in Ihrem Code wie folgt verwenden:
// Cache-Instanz abrufen $cache = Flight::cache(); $data = $cache->refreshIfExpired('simple-cache-test', function () { return date("H:i:s"); // Daten zur Zwischenspeicherung zurückgeben }, 10); // 10 Sekunden // oder $data = $cache->retrieve('simple-cache-test'); if(empty($data)) { $data = date("H:i:s"); $cache->store('simple-cache-test', $data, 10); // 10 Sekunden }
Besuchen Sie https://github.com/Wruczek/PHP-File-Cache für die vollständige Dokumentation und stellen Sie sicher, dass Sie den Beispiele-Ordner sehen.
Dies ist ein Berechtigungsmodul, das in Ihren Projekten verwendet werden kann, wenn Sie mehrere Rollen in Ihrer App haben und jede Rolle eine etwas andere Funktionalität hat. Mit diesem Modul können Sie Berechtigungen für jede Rolle definieren und dann überprüfen, ob der aktuelle Benutzer die Berechtigung hat, auf eine bestimmte Seite zuzugreifen oder eine bestimmte Aktion auszuführen.
Klicken Sie hier für das Repository auf GitHub.
Führen Sie composer require flightphp/permissions aus und los geht's!
composer require flightphp/permissions
Zuerst müssen Sie Ihre Berechtigungen einrichten, dann teilen Sie Ihrer App mit, was die Berechtigungen bedeuten. Letztendlich prüfen Sie Ihre Berechtigungen mit $Permissions->has(), ->can() oder is(). has() und can() haben die gleiche Funktionalität, sind jedoch unterschiedlich benannt, um Ihren Code leichter lesbar zu machen.
$Permissions->has()
->can()
is()
has()
can()
Angenommen, Sie haben in Ihrer Anwendung eine Funktion, die überprüft, ob ein Benutzer angemeldet ist. Sie können ein Berechtigungsobjekt wie folgt erstellen:
// index.php require 'vendor/autoload.php'; // etwas Code // dann haben Sie wahrscheinlich etwas, das Ihnen mitteilt, was die aktuelle Rolle der Person ist // wahrscheinlich haben Sie etwas, bei dem Sie die aktuelle Rolle abrufen // aus einer Session-Variablen, die dies definiert // nachdem sich jemand angemeldet hat, andernfalls haben sie die Rolle 'Gast' oder 'Öffentlich'. $current_role = 'admin'; // Berechtigungen einrichten $permission = new \flight\Permission($current_role); $permission->defineRule('eingeloggt', function($current_role) { return $current_role !== 'gast'; }); // Sie werden dieses Objekt wahrscheinlich in Flight persistieren wollen Flight::set('berechtigung', $permission);
Dann in einem Controller irgendwo haben Sie möglicherweise so etwas.
<?php // irgendein Controller class EinController { public function eineAktion() { $permission = Flight::get('berechtigung'); if ($permission->has('eingeloggt')) { // etwas machen } else { // etwas anderes machen } } }
Sie können dies auch verwenden, um zu verfolgen, ob sie Berechtigungen haben, um in Ihrer Anwendung etwas zu tun. Zum Beispiel, wenn Sie eine Möglichkeit haben, dass Benutzer Beiträge in Ihrer Software interagieren können, können Sie überprüfen, ob sie Berechtigungen haben, bestimmte Aktionen auszuführen.
$current_role = 'admin'; // Berechtigungen einrichten $permission = new \flight\Permission($current_role); $permission->defineRule('beitrag', function($current_role) { if($current_role === 'admin') { $permissions = ['erstellen', 'lesen', 'aktualisieren', 'löschen']; } else if($current_role === 'editor') { $permissions = ['erstellen', 'lesen', 'aktualisieren']; } else if($current_role === 'autor') { $permissions = ['erstellen', 'lesen']; } else if($current_role === 'mitwirkender') { $permissions = ['erstellen']; } else { $permissions = []; } return $permissions; }); Flight::set('berechtigung', $permission);
Dann irgendwo in einem Controller...
class BeitragController { public function erstellen() { $permission = Flight::get('berechtigung'); if ($permission->can('beitrag.erstellen')) { // etwas machen } else { // etwas anderes machen } } }
Sie können Abhängigkeiten in den Closure einfügen, die die Berechtigungen definieren. Dies ist nützlich, wenn Sie eine Art Schalter, ID oder einen anderen Datenpunkt haben, gegen den Sie prüfen möchten. Das Gleiche gilt für Klassen->Methoden-Aufrufe, außer dass Sie die Argumente in der Methode definieren.
$Permission->defineRule('bestellung', function(string $current_role, MyDependency $MyDependency = null) { // ... code }); // in Ihrer Controllerdatei public function bestellungErstellen() { $MyDependency = Flight::myDependency(); $permission = Flight::get('berechtigung'); if ($permission->can('bestellung.erstellen', $MyDependency)) { // etwas machen } else { // etwas anderes machen } }
namespace MeinApp; class Berechtigungen { public function bestellung(string $current_role, MyDependency $MyDependency = null) { // ... code } }
Sie können auch Klassen verwenden, um Ihre Berechtigungen zu definieren. Dies ist nützlich, wenn Sie viele Berechtigungen haben und Ihren Code sauber halten möchten. Sie können etwas Ähnliches wie folgt tun:
<?php // Startcode $Berechtigungen = new \flight\Permission($current_role); $Berechtigungen->defineRule('bestellung', 'MeinApp\Berechtigungen->bestellung'); // myapp/Berechtigungen.php namespace MeinApp; class Berechtigungen { public function bestellung(string $current_role, int $benutzer_id) { // Annehmen, dass Sie dies im Voraus eingerichtet haben /** @var \flight\database\PdoWrapper $db */ $db = Flight::db(); $erlaubte_berechtigungen = [ 'lesen' ]; // jeder kann eine Bestellung einsehen if($current_role === 'manager') { $erlaubte_berechtigungen[] = 'erstellen'; // Manager können Bestellungen erstellen } $ein_anderer_spezieller_schalter_aus_db = $db->fetchField('SELECT ein_anderer_spezieller_schalter FROM einstellungen WHERE id = ?', [ $benutzer_id ]); if($ein_anderer_spezieller_schalter_aus_db) { $erlaubte_berechtigungen[] = 'aktualisieren'; // Wenn der Benutzer einen speziellen Schalter hat, kann er Bestellungen aktualisieren } if($current_role === 'admin') { $erlaubte_berechtigungen[] = 'löschen'; // Admins können Bestellungen löschen } return $erlaubte_berechtigungen; } }
Der interessante Teil ist, dass es auch eine Abkürzung gibt, die Sie verwenden können (die auch zwischengespeichert werden kann!!!), bei der Sie der Berechtigungsklasse einfach sagen, alle Methoden in einer Klasse in Berechtigungen zu kartieren. Also, wenn Sie eine Methode namens bestellung() und eine Methode namens unternehmen() haben, werden diese automatisch zugeordnet, sodass Sie einfach $Berechtigungen->has('bestellung.lesen') oder $Berechtigungen->has('unternehmen.lesen') ausführen können und es funktioniert. Das Definieren davon ist sehr schwierig, bleiben Sie also bei mir hier. Sie müssen nur dies tun:
bestellung()
unternehmen()
$Berechtigungen->has('bestellung.lesen')
$Berechtigungen->has('unternehmen.lesen')
Erstellen Sie die Berechtigungsklasse, die Sie zusammenfassen möchten.
class MeineBerechtigungen { public function bestellung(string $current_role, int $bestellungs_id = 0): array { // Code zur Bestimmung von Berechtigungen return $berechtigungen_array; } public function unternehmen(string $current_role, int $unternehmen_id): array { // Code zur Bestimmung von Berechtigungen return $berechtigungen_array; } }
Dann machen Sie die Berechtigungen mit Hilfe dieser Bibliothek auffindbar.
$Berechtigungen = new \flight\Permission($current_role); $Berechtigungen->defineRulesFromClassMethods(MeineApp\Berechtigungen::class); Flight::set('berechtigungen', $Berechtigungen);
Rufen Sie schließlich die Berechtigung in Ihrem Code auf, um zu überprüfen, ob der Benutzer berechtigt ist, eine bestimmte Berechtigung auszuführen.
class EinController { public function bestellungErstellen() { if(Flight::get('berechtigungen')->can('bestellung.erstellen') === false) { die('Sie können keine Bestellung erstellen. Entschuldigung!'); } } }
Um die Zwischenspeicherung zu aktivieren, sehen Sie sich die einfache wruczak/phpfilecache Bibliothek an. Ein Beispiel zur Aktivierung finden Sie unten.
// dieses $app kann Teil Ihres Codes sein oder // Sie können einfach null übergeben und es wird // aus Flight::app() im Konstruktor abgerufen $app = Flight::app(); // Derzeit akzeptiert es dies als Dateipuffer. Andere können in Zukunft leicht hinzugefügt werden. $Cache = new Wruczek\PhpFileCache\PhpFileCache; $Berechtigungen = new \flight\Permission($current_role, $app, $Cache); $Berechtigungen->defineRulesFromClassMethods(MeineApp\Berechtigungen::class, 3600); // 3600 gibt an, wie viele Sekunden diese Zwischenspeicherung gültig ist. Lassen Sie dies weg, um die Zwischenspeicherung nicht zu verwenden
Flight ist unglaublich erweiterbar. Es gibt eine Reihe von Plugins, die dazu verwendet werden können, Funktionalitäten Ihrer Flight-Anwendung hinzuzufügen. Einige werden offiziell vom Flight-Team unterstützt, während andere Mikro-/Lite-Bibliotheken sind, um Ihnen den Einstieg zu erleichtern.
Caching ist ein großartiger Weg, um Ihre Anwendung zu beschleunigen. Es gibt einige Caching-Bibliotheken, die mit Flight verwendet werden können.
Debugging ist entscheidend, wenn Sie in Ihrer lokalen Umgebung entwickeln. Es gibt einige Plugins, die Ihr Debugging-Erlebnis verbessern können.
Datenbanken sind das Herzstück vieler Anwendungen. So speichern und abrufen Sie Daten. Einige Datenbank-Bibliotheken sind einfach Wrapper zum Schreiben von Abfragen, während andere vollwertige ORMs sind.
Sitzungen sind nicht wirklich nützlich für APIs, aber beim Erstellen einer Webanwendung können Sitzungen wichtig sein, um Zustands- und Anmeldeinformationen zu speichern.
Templates sind für jede Webanwendung mit einer Benutzeroberfläche unerlässlich. Es gibt eine Reihe von Templating-Engines, die mit Flight verwendet werden können.
Haben Sie ein Plugin, das Sie teilen möchten? Senden Sie einen Pull-Request, um es der Liste hinzuzufügen!
Flight wird mit einer Hilfsklasse für PDO geliefert. Es ermöglicht Ihnen, Ihre Datenbank leicht abzufragen mit all dem vorbereiteten / ausführen / fetchAll () Wahnsinn. Es vereinfacht erheblich, wie Sie können Ihre Datenbank abfragen. Jedes Zeilenergebnis wird als Flight Collection-Klasse zurückgegeben, die ermöglicht es Ihnen, auf Ihre Daten über Array-Syntax oder Objektsyntax zuzugreifen.
// Registrieren Sie die PDO-Hilfsklasse Flight::register('db', \flight\database\PdoWrapper::class, ['mysql:host=localhost;dbname=cool_db_name', 'user', 'pass', [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'utf8mb4\'', PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_STRINGIFY_FETCHES => false, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ] ]);
Dieses Objekt erweitert PDO, so dass alle normalen PDO-Methoden verfügbar sind. Die folgenden Methoden werden hinzugefügt, um das Abfragen der Datenbank zu erleichtern:
runQuery(string $sql, array $params = []): PDOStatement
Verwenden Sie dies für INSERTS, UPDATES oder wenn Sie planen, ein SELECT in einer Schleife zu verwenden
$db = Flight::db(); $statement = $db->runQuery("SELECT * FROM table WHERE something = ?", [ $something ]); while($row = $statement->fetch()) { // ... } // Oder Schreiben in die Datenbank $db->runQuery("INSERT INTO table (name) VALUES (?)", [ $name ]); $db->runQuery("UPDATE table SET name = ? WHERE id = ?", [ $name, $id ]);
fetchField(string $sql, array $params = []): mixed
Holt das erste Feld aus der Abfrage
$db = Flight::db(); $count = $db->fetchField("SELECT COUNT(*) FROM table WHERE something = ?", [ $something ]);
fetchRow(string $sql, array $params = []): array
Holt eine Zeile aus der Abfrage
$db = Flight::db(); $row = $db->fetchRow("SELECT id, name FROM table WHERE id = ?", [ $id ]); echo $row['name']; // oder echo $row->name;
fetchAll(string $sql, array $params = []): array
Holt alle Zeilen aus der Abfrage
$db = Flight::db(); $rows = $db->fetchAll("SELECT id, name FROM table WHERE something = ?", [ $something ]); foreach($rows as $row) { echo $row['name']; // oder echo $row->name; }
IN()
Hierfür gibt es auch ein hilfreiches Wrapper für IN()-Anweisungen. Sie können einfach ein einzelnes Fragezeichen als Platzhalter für IN() übergeben und dann ein Array von Werten. Hier ist ein Beispiel dafür, wie das aussehen könnte:
$db = Flight::db(); $name = 'Bob'; $company_ids = [1,2,3,4,5]; $rows = $db->fetchAll("SELECT id, name FROM table WHERE name = ? AND company_id IN (?)", [ $name, $company_ids ]);
// Beispielroute und wie Sie diesen Wrapper verwenden würden Flight::route('/benutzer', function () { // Holen Sie sich alle Benutzer $users = Flight::db()->fetchAll('SELECT * FROM users'); // Streamen Sie alle Benutzer $statement = Flight::db()->runQuery('SELECT * FROM users'); while ($user = $statement->fetch()) { echo $user['name']; // oder echo $user->name; } // Holen Sie sich einen einzelnen Benutzer $user = Flight::db()->fetchRow('SELECT * FROM users WHERE id = ?', [123]); // Holen Sie sich einen einzelnen Wert $count = Flight::db()->fetchField('SELECT COUNT(*) FROM users'); // Besondere IN()-Syntax zur Unterstützung (stellen Sie sicher, dass IN großgeschrieben ist) $users = Flight::db()->fetchAll('SELECT * FROM users WHERE id IN (?)', [[1,2,3,4,5]]); // Sie könnten auch dies tun $users = Flight::db()->fetchAll('SELECT * FROM users WHERE id IN (?)', [ '1,2,3,4,5']); // Fügen Sie einen neuen Benutzer ein Flight::db()->runQuery("INSERT INTO users (name, email) VALUES (?, ?)", ['Bob', 'bob@example.com']); $insert_id = Flight::db()->lastInsertId(); // Aktualisieren Sie einen Benutzer Flight::db()->runQuery("UPDATE users SET name = ? WHERE id = ?", ['Bob', 123]); // Löschen eines Benutzers Flight::db()->runQuery("DELETE FROM users WHERE id = ?", [123]); // Abrufen der Anzahl der betroffenen Zeilen $statement = Flight::db()->runQuery("UPDATE users SET name = ? WHERE name = ?", ['Bob', 'Sally']); $affected_rows = $statement->rowCount(); });
PHP-Sitzungsverwaltung (nicht blockierend, Flash, Segment, Sitzungsverschlüsselung). Verwendet PHP open_ssl zur optionalen Verschlüsselung/Entschlüsselung von Sitzungsdaten. Unterstützt Datei, MySQL, Redis und Memcached.
Installation mit Composer.
composer require geist/session
Es ist nicht erforderlich, etwas zu übergeben, um die Standardeinstellungen für Ihre Sitzung zu verwenden. Weitere Einstellungen finden Sie im Github-Readme.
Verwendung von Geist\Session\Session; Erfordert 'vendor/autoload.php'; $app = Flight::app(); $app->register('session', Sitzung::class); // Eine Sache, die Sie beachten müssen, ist, dass Sie bei jedem Seitenaufruf Ihre Sitzung bestätigen müssen // oder Sie müssen auto_commit in Ihrer Konfiguration ausführen.
Hier ist ein einfaches Beispiel, wie Sie dies verwenden könnten.
Flight::route('POST /login', function() { $sitzung = Flight::session(); // Führen Sie hier Ihre Anmelde-Logik aus // Passwort überprüfen, usw. // Wenn die Anmeldung erfolgreich ist $sitzung->set('is_logged_in', true); $sitzung->set('user', $user); // Jedes Mal, wenn Sie in die Sitzung schreiben, müssen Sie sie bewusst bestätigen. $sitzung->commit(); }); // Diese Überprüfung könnte in der Logik der eingeschränkten Seite sein oder mit Middleware umhüllt sein. Flight::route('/some-restricted-page', function() { $sitzung = Flight::session(); if(!$sitzung->get('is_logged_in')) { Flight::redirect('/login'); } // Führen Sie hier Ihre Logik für die eingeschränkte Seite aus }); // die Middleware-Version Flight::route('/some-restricted-page', function() { // normale Seitenlogik })->addMiddleware(function() { $sitzung = Flight::session(); if(!$sitzung->get('is_logged_in')) { Flight::redirect('/login'); } });
Hier ist ein komplexeres Beispiel, wie Sie dies verwenden könnten.
Verwendung von Geist\Session\Session; Erfordert 'vendor/autoload.php'; $app = Flight::app(); // Setzen Sie einen benutzerdefinierten Pfad zu Ihrer Sitzungskonfigurationsdatei und geben Sie ihm eine Zufalls Zeichenfolge für die Sitzungs-ID $app->register('session', Sitzung::class, [ 'pfad/zur/sitzungskonfig.php', bin2hex(random_bytes(32)) ], function(Sitzung $sitzung) { // oder Sie können Konfigurationsoptionen manuell überschreiben $sitzung->updateConfiguration([ // Wenn Sie Ihre Sitzungsdaten in einer Datenbank speichern möchten (gut, wenn Sie etwas wie "Abmelden von allen Geräten" Funktion benötigen) Sitzung::CONFIG_DRIVER => Geist\Session\Drivers\MySql::class, Sitzung::CONFIG_ENCRYPT_DATA => true, Sitzung::CONFIG_SALT_KEY => hash('sha256', 'mein-super-GEH3IM-salz'), // bitte ändern Sie dies in etwas anderes Sitzung::CONFIG_AUTO_COMMIT => true, // Nur machen Sie das, wenn es erforderlich ist und/oder schwer ist, Ihre Sitzung zu commiten. // zusätzlich könnten Sie machen Flight::after('start', function() { Flight::session()->commit(); });; Sitzung::CONFIG_MYSQL_DS => [ 'driver' => 'mysql', # Datenbanktreiber für PDO-DNS z.B. (mysql:host=...;dbname=...) 'host' => '127.0.0.1', # Datenbank-Host 'db_name' => 'meine_app_datenbank', # Datenbankname 'db_table' => 'sitzungen', # Datenbanktabelle 'db_user' => 'root', # Datenbankbenutzername 'db_pass' => '', # Datenbankpasswort 'persistent_conn'=> false, # Vermeiden Sie den Overhead beim Aufbau einer neuen Verbindung, wenn ein Skript mit einer Datenbank sprechen muss, was zu einer schnelleren Webanwendung führt. FINDEN SIE DIE RÜCKSEITE SELBST ] ]); } );
Wenn Sie Ihre Sitzungsdaten festlegen und sie zwischen Anfragen nicht bestehen bleiben, haben Sie möglicherweise vergessen, Ihre Sitzungsdaten zu bestätigen. Sie können dies tun, indem Sie nach dem Festlegen Ihrer Sitzungsdaten $sitzung->commit() aufrufen.
$sitzung->commit()
Flight::route('POST /login', function() { $sitzung = Flight::session(); // Führen Sie hier Ihre Anmelde-Logik aus // Passwort überprüfen, usw. // Wenn die Anmeldung erfolgreich ist $sitzung->set('is_logged_in', true); $sitzung->set('user', $user); // Jedes Mal, wenn Sie in die Sitzung schreiben, müssen Sie sie bewusst bestätigen. $sitzung->commit(); });
Der andere Weg, dies zu umgehen, ist, wenn Sie Ihren Sitzungsdienst einrichten, müssen Sie auto_commit in Ihrer Konfiguration auf true setzen. Dadurch werden Ihre Sitzungsdaten automatisch nach jeder Anfrage bestätigt.
auto_commit
$app->register('session', Sitzung::class, [ 'pfad/zur/sitzungskonfig.php', bin2hex(random_bytes(32)) ], function(Sitzung $sitzung) { $sitzung->updateConfiguration([ Sitzung::CONFIG_AUTO_COMMIT => true, ]); } );
Zusätzlich könnten Sie Flight::after('start', function() { Flight::session()->commit(); }); verwenden, um Ihre Sitzungsdaten nach jeder Anfrage zu bestätigen.
Flight::after('start', function() { Flight::session()->commit(); });
Besuchen Sie das Github-Readme für die vollständige Dokumentation. Die Konfigurationsoptionen sind im default_config.php selbst gut dokumentiert. Der Code ist einfach zu verstehen, wenn Sie dieses Paket selbst durchgehen möchten.
Startbahn ist eine CLI-Anwendung, die Ihnen dabei hilft, Ihre Flight-Anwendungen zu verwalten. Sie kann Controller generieren, alle Routen anzeigen und mehr. Sie basiert auf der ausgezeichneten adhocore/php-cli Bibliothek.
Klicken Sie hier, um den Code anzusehen.
Mit Composer installieren.
composer require flightphp/startbahn
Das erste Mal, wenn Sie Startbahn ausführen, wird es Sie durch einen Einrichtungsprozess führen und eine .runway.json-Konfigurationsdatei im Stammverzeichnis Ihres Projekts erstellen. Diese Datei wird einige notwendige Konfigurationen enthalten, damit Startbahn ordnungsgemäß funktioniert.
Startbahn hat mehrere Befehle, die Sie verwenden können, um Ihre Flight-Anwendung zu verwalten. Es gibt zwei einfache Möglichkeiten, Startbahn zu verwenden.
php startbahn [Befehl]
vendor/bin/startbahn [Befehl]
Für jeden Befehl können Sie die --help-Flagge übergeben, um weitere Informationen zur Verwendung des Befehls zu erhalten.
--help
php startbahn routes --help
Hier sind ein paar Beispiele:
Basierend auf der Konfiguration in Ihrer .runway.json-Datei wird der Standardort einen Controller für Sie im app/controllers/ Verzeichnis generieren.
app/controllers/
php startbahn make:controller MeinController
Basierend auf der Konfiguration in Ihrer .runway.json-Datei wird der Standardort einen Controller für Sie im app/records/ Verzeichnis generieren.
app/records/
php startbahn make:record benutzer
Wenn Sie zum Beispiel die benutzer Tabelle mit dem folgenden Schema haben: id, name, email, created_at, updated_at, wird eine Datei ähnlich der folgenden in der app/records/BenutzerDatensatz.php erstellt:
benutzer
email
created_at
updated_at
app/records/BenutzerDatensatz.php
<?php declare(strict_types=1); namespace app\records; /** * ActiveRecord-Klasse für die benutzer Tabelle. * @link https://docs.flightphp.com/awesome-plugins/active-record * * @property int $id * @property string $name * @property string $email * @property string $created_at * @property string $updated_at * // Sie können hier auch Beziehungen hinzufügen, sobald Sie sie im $relations-Array definieren * @property CompanyRecord $company Beispiel für eine Beziehung */ class BenutzerDatensatz erstreckt sich über \flight\ActiveRecord { /** * @var array $relations Setzen Sie die Beziehungen für das Modell * https://docs.flightphp.com/awesome-plugins/active-record#relationships */ protected array $relations = []; /** * Konstruktor * @param gemischt $datenbankverbindung Die Verbindung zur Datenbank */ public function __construct($datenbankverbindung) { parent::__construct($datenbankverbindung, 'benutzer'); } }
Dies wird alle Routen anzeigen, die derzeit bei Flight registriert sind.
php startbahn routes
Wenn Sie nur bestimmte Routen anzeigen möchten, können Sie eine Flagge übergeben, um die Routen zu filtern.
# Nur GET-Routen anzeigen php startbahn routes --get # Nur POST-Routen anzeigen php startbahn routes --post # usw.
Wenn Sie entweder ein Paket für Flight erstellen oder Ihre eigenen benutzerdefinierten Befehle in Ihr Projekt integrieren möchten, können Sie dies tun, indem Sie ein src/befehle/, flight/befehle/, app/befehle/ oder befehle/ Verzeichnis für Ihr Projekt/Paket erstellen.
src/befehle/
flight/befehle/
app/befehle/
befehle/
Um einen Befehl zu erstellen, erweitern Sie einfach die Klasse AbstractBaseCommand und implementieren Sie mindestens eine __construct-Methode und eine ausführen-Methode.
AbstractBaseCommand
__construct
ausführen
<?php declare(strict_types=1); namespace flight\commands; Klasse BeispielBefehl erweitert AbstractBaseCommand { /** * Konstruieren * * @param array<string, gemischt> $konfig JSON-Konfiguration aus .runway-config.json */ public function __construct(array $konfig) { parent::__construct('make:beispiel', 'Erstellt ein Beispiel für die Dokumentation', $konfig); $this->argument('<lustiges-gif>', 'Der Name des lustigen Gifs'); } /** * Führt die Funktion aus * * @return Leer */ public function execute(string $controller) { $io = $this->app()->io(); $io->info('Beispiel wird erstellt...'); // Hier etwas machen $io->ok('Beispiel erstellt!'); } }
Siehe die adhocore/php-cli Dokumentation für weitere Informationen, wie Sie Ihre eigenen benutzerdefinierten Befehle in Ihre Flight-Anwendung integrieren können!
Dies ist eine Sammlung von Erweiterungen, um die Arbeit mit Flight etwas komfortabler zu gestalten.
$_SESSION
Dies ist das Panel
Und jedes Panel zeigt sehr hilfreiche Informationen über Ihre Anwendung!
Klicke hier, um den Code anzusehen.
Führen Sie composer require flightphp/tracy-extensions --dev aus und los geht's!
composer require flightphp/tracy-extensions --dev
Es gibt sehr wenig Konfiguration, die Sie benötigen, um dies zu starten. Sie müssen den Tracy-Debugger initialisieren, bevor Sie dies verwenden https://tracy.nette.org/en/guide:
<?php use Tracy\Debugger; use flight\debug\tracy\TracyExtensionLoader; // Bootstrap-Code require __DIR__ . '/vendor/autoload.php'; Debugger::enable(); // Möglicherweise müssen Sie Ihre Umgebung mit Debugger::enable(Debugger::DEVELOPMENT) angeben // Wenn Sie Datenbankverbindungen in Ihrer App verwenden, gibt es einen // erforderlichen PDO-Wrapper, der NUR IN DER ENTWICKLUNG verwendet werden sollte (bitte nicht in der Produktion!) // Er hat die gleichen Parameter wie eine reguläre PDO-Verbindung $pdo = new PdoQueryCapture('sqlite:test.db', 'user', 'pass'); // Oder wenn Sie dies an das Flight-Framework anhängen Flight::register('db', PdoQueryCapture::class, ['sqlite:test.db', 'user', 'pass']); // Jetzt erfasst es die Zeit, die Abfrage und die Parameter, wann immer Sie eine Abfrage machen // Dies verbindet die Punkte if(Debugger::$showBar === true) { // Dies muss falsch sein, oder Tracy kann tatsächlich nicht gerendert werden :( Flight::set('flight.content_length', false); new TracyExtensionLoader(Flight::app()); } // mehr Code Flight::start();
Wenn Sie einen benutzerdefinierten Sitzungshandler haben (wie z.B. ghostff/session), können Sie beliebige Sitzungsdaten an Tracy übergeben, und es wird sie automatisch für Sie ausgeben. Übergeben Sie es mit dem session_data-Schlüssel im zweiten Parameter des Konstruktors von TracyExtensionLoader.
session_data
TracyExtensionLoader
use Ghostff\Session\Session; require 'vendor/autoload.php'; $app = Flight::app(); $app->register('session', Session::class); if(Debugger::$showBar === true) { // Dies muss falsch sein, oder Tracy kann tatsächlich nicht gerendert werden :( Flight::set('flight.content_length', false); new TracyExtensionLoader(Flight::app(), [ 'session_data' => Flight::session()->getAll() ]); } // Routen und andere Dinge... Flight::start();
Wenn Sie Latte in Ihrem Projekt installiert haben, können Sie das Latte-Panel verwenden, um Ihre Vorlagen zu analysieren. Sie können die Latte-Instanz an den TracyExtensionLoader-Konstruktor mit dem latte-Schlüssel im zweiten Parameter übergeben.
latte
use Latte\Engine; require 'vendor/autoload.php'; $app = Flight::app(); $app->register('latte', Engine::class, [], function($latte) { $latte->setTempDirectory(__DIR__ . '/temp'); // Hier fügen Sie das Latte Panel zu Tracy hinzu $latte->addExtension(new Latte\Bridges\Tracy\TracyExtension); }); if(Debugger::$showBar === true) { // Dies muss falsch sein, oder Tracy kann tatsächlich nicht gerendert werden :( Flight::set('flight.content_length', false); new TracyExtensionLoader(Flight::app()); }
Tracy ist ein erstaunlicher Fehlerhandler, der mit Flight verwendet werden kann. Es verfügt über eine Reihe von Panels, die Ihnen bei der Fehlerbehebung Ihrer Anwendung helfen können. Es ist auch sehr einfach zu erweitern und eigene Panels hinzuzufügen. Das Flight-Team hat speziell für Flight-Projekte mit dem flightphp/tracy-extensions Plugin einige Panels erstellt.
Installiere es mit Composer. Und in der Tat möchten Sie dies ohne die Entwicklerversion installieren, da Tracy mit einem Produktionsfehlerbehandlungskomponente geliefert wird.
composer require tracy/tracy
Es gibt einige grundlegende Konfigurationsoptionen, um loszulegen. Weitere Informationen dazu finden Sie in der Tracy-Dokumentation.
require 'vendor/autoload.php'; use Tracy\Debugger; // Aktiviere Tracy Debugger::enable(); // Debugger::enable(Debugger::DEVELOPMENT) // Manchmal müssen Sie explizit sein (auch Debugger::PRODUCTION) // Debugger::enable('23.75.345.200'); // Sie können auch ein Array von IP-Adressen bereitstellen // Hier werden Fehler und Ausnahmen protokolliert. Stellen Sie sicher, dass dieses Verzeichnis vorhanden ist und beschreibbar ist. Debugger::$logDirectory = __DIR__ . '/../log/'; Debugger::$strictMode = true; // alle Fehler anzeigen // Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // alle Fehler außer veralteten Hinweisen if (Debugger::$showBar) { $app->set('flight.content_length', false); // Wenn die Debugger-Leiste sichtbar ist, kann die Inhaltslänge nicht von Flight festgelegt werden // Dies ist spezifisch für die Tracy-Erweiterung für Flight, wenn Sie diese eingeschlossen haben // Andernfalls kommentieren Sie dies aus. new TracyExtensionLoader($app); }
Wenn Sie Ihren Code debuggen, gibt es einige sehr hilfreiche Funktionen, um Daten für Sie auszugeben.
bdump($var)
dumpe($var)
Ein aktiver Datensatz ordnet eine Datenbankeinheit einem PHP-Objekt zu. Einfach ausgedrückt, wenn Sie eine Benutzertabelle in Ihrer Datenbank haben, können Sie eine Zeile in dieser Tabelle in eine Benutzer-Klasse und ein $benutzer-Objekt in Ihrem Code übersetzen. Siehe Grundbeispiel.
Benutzer
$benutzer
Nehmen wir an, Sie haben die folgende Tabelle:
CREATE TABLE benutzer ( id INTEGER PRIMARY KEY, name TEXT, passwort TEXT );
Jetzt können Sie eine neue Klasse einrichten, die diese Tabelle darstellt:
/** * Eine ActiveRecord-Klasse ist in der Regel im Singular * * Es wird dringend empfohlen, die Eigenschaften der Tabelle hier als Kommentare hinzuzufügen * * @property int $id * @property string $name * @property string $password */ class Benutzer erstreckt sich flight\ActiveRecord { public function __construct($datenbank_verbindung) { // Sie können es auf diese Weise festlegen parent::__construct($datenbank_verbindung, 'benutzer'); // oder so parent::__construct($datenbank_verbindung, null, [ 'tabelle' => 'benutzer']); } }
Schauen Sie nun, wie die Magie passiert!
// für SQLite $datenbank_verbindung = new PDO('sqlite:test.db'); // Dies ist nur ein Beispiel, Sie würden wahrscheinlich eine echte Datenbankverbindung verwenden // für MySQL $datenbank_verbindung = new PDO('mysql:host=localhost;dbname=test_db&charset=utf8bm4', 'benutzername', 'passwort'); // oder mysqli $datenbank_verbindung = new mysqli('localhost', 'benutzername', 'passwort', 'test_db'); // oder mysqli mit nicht-objektbasierter Erstellung $datenbank_verbindung = mysqli_connect('localhost', 'benutzername', 'passwort', 'test_db'); $benutzer = new Benutzer($datenbank_verbindung); $benutzer->name = 'Bobby Tables'; $benutzer->password = password_hash('Ein cooles Passwort'); $benutzer->einfügen(); // oder $benutzer->speichern(); echo $benutzer->id; // 1 $benutzer->name = 'Joseph Mamma'; $benutzer->password = password_hash('nochmal ein cooles Passwort!!!'); $benutzer->insert(); // Hier kann $user->save() nicht verwendet werden, da sonst angenommen wird, dass es ein Update ist! echo $benutzer->id; // 2
Und es war so einfach, einen neuen Benutzer hinzuzufügen! Jetzt, da es einen Benutzerdatensatz in der Datenbank gibt, wie können Sie ihn herausholen?
$benutzer->find(1); // Finde id = 1 in der Datenbank und gib ihn zurück. echo $benutzer->name; // 'Bobby Tables'
Und was ist, wenn Sie alle Benutzer finden möchten?
$benutzer = $user->findAll();
Was ist mit einer bestimmten Bedingung?
$benutzer = $user->like('name', '%mamma%')->findAll();
Sehen Sie, wie viel Spaß das macht? Lassen Sie uns es installieren und loslegen!
Einfach mit Composer installieren
composer require flightphp/active-record
Dies kann als eigenständige Bibliothek oder mit dem Flight PHP Framework verwendet werden. Ganz wie Sie möchten.
Stellen Sie einfach sicher, dass Sie eine PDO-Verbindung an den Konstruktor übergeben.
$pdo_verbindung = new PDO('sqlite:test.db'); // Dies ist nur ein Beispiel, Sie würden wahrscheinlich eine echte Datenbankverbindung verwenden. $Benutzer = new Benutzer($pdo_verbindung);
Möchten Sie Ihre Datenbankverbindung nicht immer im Konstruktor festlegen? Sehen Sie sich Verwaltung der Datenbankverbindung für andere Ideen an!
Wenn Sie das Flight PHP Framework nutzen, können Sie die ActiveRecord-Klasse als Dienst registrieren, aber Sie müssen dies ehrlich gesagt nicht tun.
Flight::register('benutzer', 'Benutzer', [ $pdo_verbindung ]); // dann können Sie es in einem Controller, einer Funktion usw. verwenden Flight::benutzer()->find(1);
runway
runway ist ein CLI-Tool für Flight, das über ein benutzerdefiniertes Steuerungsprogramm für diese Bibliothek verfügt.
# Verwendung php runway make:record database_table_name [class_name] # Beispiel php runway make:record benutzer
Dies erstellt eine neue Klasse im Verzeichnis app/records/ als UserRecord.php mit folgendem Inhalt:
UserRecord.php
<?php declare(strict_types=1); namespace app\records; /** * ActiveRecord-Klasse für die Benutzertabelle. * @link https://docs.flightphp.com/awesome-plugins/active-record * * @property int $id * @property string $name * @property string $email * @property string $password_hash * @property string $created_dt */ class UserRecord extends \flight\ActiveRecord { /** * @var array $relations Setzt die Beziehungen für das Modell * https://docs.flightphp.com/awesome-plugins/active-record#verknüpfungen */ protected array $relations = [ // 'relation_name' => [ self::HAS_MANY, 'RelatedClass', 'foreign_key' ], ]; /** * Konstruktor * @param mixed $databaseConnection Die Verbindung zur Datenbank */ public function __construct($databaseConnection) { parent::__construct($databaseConnection, 'benutzer'); } }
find($id = null) : boolean|ActiveRecord
Sucht einen Datensatz und weist ihn dem aktuellen Objekt zu. Wenn Sie eine $id von irgendeiner Art übergeben, erfolgt eine Abfrage des Primärschlüssels mit diesem Wert. Wenn nichts übergeben wird, wird einfach der erste Datensatz in der Tabelle gefunden.
Zusätzlich können Sie ihm andere Hilfsmethoden übergeben, um Ihre Tabelle abzufragen.
// Suchen Sie einen Datensatz mit bestimmten Bedingungen im Voraus $benutzer->notNull('password')->orderBy('id DESC')->find(); // Suchen Sie einen Datensatz anhand einer bestimmten ID $id = 123; $benutzer->find($id);
findAll(): array<int,ActiveRecord>
Findet alle Datensätze in der von Ihnen angegebenen Tabelle.
$benutzer->findAll();
isHydrated(): boolean
Gibt true zurück, wenn der aktuelle Datensatz geholt (aus der Datenbank abgerufen) wurde.
$benutzer->find(1); // wenn ein Datensatz mit Daten gefunden wird... $benutzer->isHydrated(); // true
insert(): boolean|ActiveRecord
Fügt den aktuellen Datensatz in die Datenbank ein.
$benutzer = new Benutzer($pdo_verbindung); $benutzer->name = 'Demo'; $benutzer->password = md5('Demo'); $benutzer->insert();
Wenn Sie einen textbasierten Primärschlüssel haben (wie z.B. eine UUID), können Sie den Primärschlüsselwert vor dem Einfügen auf zwei Arten festlegen.
$benutzer = new Benutzer($pdo_verbindung, [ 'primaryKey' => 'uuid' ]); $benutzer->uuid = 'Einige-UUID'; $benutzer->name = 'Demo'; $benutzer->password = md5('Demo'); $benutzer->insert(); // oder $benutzer->save();
oder Sie können den Primärschlüssel automatisch generieren lassen, indem Sie Ereignisse verwenden.
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'benutzer', [ 'primaryKey' => 'uuid' ]); // können Sie auch den Primärschlüssel auf diese Weise festlegen, anstatt des obigen Arrays. $this->primaryKey = 'uuid'; } protected function beforeInsert(self $self) { $self->uuid = uniqid(); // oder wie auch immer Sie Ihre eindeutigen IDs generieren müssen } }
Wenn Sie den Primärschlüssel vor dem Einfügen nicht festlegen, wird er auf den rowid gesetzt und die Datenbank wird ihn für Sie generieren, aber er wird nicht gespeichert, da dieses Feld in Ihrer Tabelle möglicherweise nicht existiert. Deshalb wird empfohlen, das Ereignis zu verwenden, um dies automatisch für Sie zu behandeln.
rowid
update(): boolean|ActiveRecord
Aktualisiert den aktuellen Datensatz in der Datenbank.
$benutzer->greaterThan('id', 0)->orderBy('id desc')->find(); $benutzer->email = 'test@example.com'; $benutzer->update();
save(): boolean|ActiveRecord
Fügt den aktuellen Datensatz in die Datenbank ein oder aktualisiert ihn. Wenn der Datensatz eine ID hat, wird er aktualisiert, andernfalls wird er eingefügt.
$benutzer = new Benutzer($pdo_verbindung); $benutzer->name = 'Demo'; $benutzer->password = md5('Demo'); $benutzer->save();
Anmerkung: Wenn in der Klasse Beziehungen definiert sind, werden diese Beziehungen rekursiv gespeichert, wenn sie definiert, instanziiert und schmutzige Daten zum Aktualisieren haben (ab Version 0.4.0).
delete(): boolean
Löscht den aktuellen Datensatz aus der Datenbank.
$benutzer->gt('id', 0)->orderBy('id desc')->find(); $benutzer->delete();
Sie können auch mehrere Datensätze löschen, indem Sie zuerst eine Suche durchführen.
$benutzer->like('name', 'Bob%')->delete();
dirty(array $dirty = []): ActiveRecord
Schmutzige Daten beziehen sich auf die Daten, die in einem Datensatz geändert wurden.
$benutzer->greaterThan('id', 0)->orderBy('id desc')->find(); // Es gibt bis zu diesem Zeitpunkt nichts "schmutziges". $benutzer->email = 'test@example.com'; // Jetzt gilt die E-Mail-Adresse als "schmutzig", da sie geändert wurde. $benutzer->update(); // Jetzt gibt es keine schmutzigen Daten mehr, weil sie aktualisiert und in der Datenbank gespeichert wurden. $benutzer->password = password_hash()'neuespasswort'); // Jetzt ist dies schmutzig $benutzer->dirty(); // Das Übergeben von nichts löscht alle schmutzigen Einträge. $benutzer->update(); // Nichts wird aktualisiert, da nichts als schmutzig erfasst wurde. $benutzer->dirty([ 'name' => 'etwas', 'password' => password_hash('ein anderes Passwort') ]); $benutzer->update(); // sowohl Name als auch Passwort werden aktualisiert.
copyFrom(array $data): ActiveRecord
Dies ist ein Alias für die Methode dirty(). Es ist etwas klarer, was Sie tun.
dirty()
$benutzer->copyFrom([ 'name' => 'etwas', 'password' => password_hash('ein anderes Passwort') ]); $benutzer->update(); // sowohl Name als auch Passwort werden aktualisiert.
isDirty(): boolean
Gibt true zurück, wenn der aktuelle Datensatz geändert wurde.
$benutzer->greaterThan('id', 0)->orderBy('id desc')->find(); $benutzer->email = 'test@email.com'; $benutzer->isDirty(); // true
reset(bool $include_query_data = true): ActiveRecord
Setzt den aktuellen Datensatz auf seinen Ausgangszustand zurück. Dies ist wirklich gut für Schleifenverhalten. Wenn Sie true übergeben, werden auch die Abfragedaten zurückgesetzt, die zum Finden des aktuellen Objekts verwendet wurden (Standardverhalten).
$benutzer = $benutzer->greaterThan('id', 0)->orderBy('id desc')->find(); $user_company = new UserCompany($pdo_verbindung); foreach($benutzer as $benutzer) { $user_company->reset(); // mit einem sauberen Blatt beginnen $user_company->user_id = $benutzer->id; $user_company->company_id = $some_company_id; $user_company->insert(); }
getBuiltSql(): string
Nach Ausführung einer find(), findAll(), insert(), update() oder save()-Methode können Sie den erstellten SQL abrufen und für Debug-Zwecke verwenden.
find()
findAll()
insert()
update()
save()
select(string $field1 [, string $field2 ... ])
Sie können nur einige der Spalten in einer Tabelle auswählen, wenn Sie möchten (was bei sehr breiten Tabellen mit vielen Spalten performanter ist).
$benutzer->select('id', 'name')->find();
from(string $table)
Sie können theoretisch auch eine andere Tabelle auswählen! Warum nicht?!
$benutzer->select('id', 'name')->from('benutzer')->find();
join(string $table_name, string $join_condition)
Sie können sogar mit einer anderen Tabelle in der Datenbank verknüpfen.
$benutzer->join('kontakte', 'kontakte.benutzer_id = benutzer.id')->find();
where(string $where_conditions)
Sie können benutzerdefinierte where-Argumente festlegen (Sie können in dieser where-Anweisung keine Parameter festlegen)
$benutzer->where('id=1 AND name="demo"')->find();
Sicherheitshinweis - Sie könnten versucht sein, etwas wie $benutzer->where("id = '{$id}' AND name = '{$name}'")->find(); zu tun. Bitte TUN SIE DAS NICHT!!! Dies ist anfällig für das, was als SQL-Injection-Angriffe bekannt ist. Es gibt viele Artikel online, suchen Sie bitte nach "SQL-Injektionsangriffen php", und Sie finden viele Artikel zu diesem Thema. Der richtige Umgang damit mit dieser Bibliothek ist anstelle dieser where()-Methode etwas wie $benutzer->eq('id', $id)->eq('name', $name)->find(); zu tun. Wenn Sie dies unbedingt tun müssen, bietet die PDO-Bibliothek $pdo->quote($var) an, um es für Sie zu escapen. Erst nach Verwendung von quote() können Sie es in einer where()-Anweisung verwenden.
$benutzer->where("id = '{$id}' AND name = '{$name}'")->find();
where()
$benutzer->eq('id', $id)->eq('name', $name)->find();
$pdo->quote($var)
quote()
group(string $group_by_statement)/groupBy(string $group_by_statement)
Gruppieren Sie Ihre Ergebnisse nach einer bestimmten Bedingung.
$benutzer->select('COUNT(*) as count')->groupBy('name')->findAll();
order(string $order_by_statement)/orderBy(string $order_by_statement)
Sortieren Sie die zurückgegebene Abfrage auf eine bestimmte Weise.
$benutzer->orderBy('name DESC')->find();
limit(string $limit)/limit(int $offset, int $limit)
Begrenzen Sie die Anzahl der zurückgegebenen Datensätze. Wenn ein zweites Int übergeben wird, wird es wie in SQL als Offset und Limit verwendet.
$benutzer->orderby('name DESC')->limit(0, 10)->findAll();
equal(string $field, mixed $value) / eq(string $field, mixed $value)
Wo field = $value
field = $value
$benutzer->eq('id', 1)->find();
notEqual(string $field, mixed $value) / ne(string $field, mixed $value)
Wo field <> $value
field <> $value
$benutzer->ne('id', 1)->find();
isNull(string $field)
Wo field IS NULL
field IS NULL
$benutzer->isNull('id')->find();
isNotNull(string $field) / notNull(string $field)
Wo field IS NOT NULL
field IS NOT NULL
$benutzer->isNotNull('id')->find();
greaterThan(string $field, mixed $value) / gt(string $field, mixed $value)
Wo field > $value
field > $value
$benutzer->gt('id', 1)->find();
lessThan(string $field, mixed $value) / lt(string $field, mixed $value)
Wo field < $value
field < $value
$benutzer->lt('id', 1)->find();
greaterThanOrEqual(string $field, mixed $value) / ge(string $field, mixed $value) / gte(string $field, mixed $value)
Wo field >= $value
field >= $value
$benutzer->ge('id', 1)->find();
lessThanOrEqual(string $field, mixed $value) /le(string $field, mixed $value) / lte(string $field, mixed $value)
Wo field <= $value
field <= $value
$benutzer->le('id', 1)->find();
like(string $field, mixed $value) / notLike(string $field, mixed $value)
Wo field LIKE $value oder field NOT LIKE $value
field LIKE $value
field NOT LIKE $value
$benutzer->like('name', 'de')->find();
in(string $field, array $values) / notIn(string $field, array $values)
Wo field IN($value) oder field NOT IN($value)
field IN($value)
field NOT IN($value)
$benutzer->in('id', [1, 2])->find();
between(string $field, array $values)
Wo field BETWEEN $value AND $value1
field BETWEEN $value AND $value1
$benutzer->between('id', [1, 2])->find();
Sie können mit dieser Bibliothek verschiedene Arten von Beziehungen festlegen. Sie können zwischen Tabellen eine-eine und eine-viele Beziehungen festlegen. Dafür ist eine kleine zusätzliche Einrichtung in der Klasse erforderlich.
Das Setzen des $relations-Arrays ist nicht schwer, aber das Erraten der richtigen Syntax kann verwirrend sein.
$relations
protected array $relations = [ // Sie können den Schlüssel beliebig benennen. Der Name des ActiveRecords ist wahrscheinlich gut. z.B.: user, contact, client 'user' => [ // erforderlich // self::HAS_MANY, self::HAS_ONE, self::BELONGS_TO self::HAS_ONE, // dies ist der Beziehungstyp // erforderlich 'Some_Class', // dies ist die "andere" ActiveRecord-Klasse, auf die verwiesen wird // erforderlich // je nach Beziehungstyp // self::HAS_ONE = der Fremdschlüssel, der auf das Join verweist // self::HAS_MANY = der Fremdschlüssel, der auf das Join verweist // self::BELONGS_TO = der lokale Schlüssel, der auf das Join verweist 'lokal_oder_fremdschlüssel', // nur zur Information, verknüpft dies auch nur mit dem Primärschlüssel des "anderen" Modells // optional [ 'eq' => [ 'client_id', 5 ], 'select' => 'COUNT(*) as count', 'limit' 5 ], // zusätzliche Bedingungen, die Sie bei der Verknüpfung der Beziehung wünschen // $record->eq('client_id', 5)->select('COUNT(*) as count')->limit(5)) // optional 'back_reference_name' // dies ist, wenn Sie diese Beziehung zurückverfolgen möchten zurück zu sich selbst z.B.: $user->contact->user; ]; ]
class User extends ActiveRecord{ protected array $relations = [ 'kontakte' => [ self::HAS_MANY, Kontakt::class, 'benutzer_id' ], 'kontakt' => [ self::HAS_ONE, Kontakt::class, 'benutzer_id' ], ]; public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'benutzer'); } } class Contact extends ActiveRecord{ protected array $relations = [ 'user' => [ self::BELONGS_TO, User::class, 'benutzer_id' ], 'user_with_backref' => [ self::BELONGS_TO, User::class, 'benutzer_id', [], 'contact' ], ]; public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'kontakte'); } }
Jetzt sind die Referenzen eingerichtet, sodass wir sie sehr einfach verwenden können!
$user = new User($pdo_verbindung); // finden Sie den neuesten Benutzer. $benutzer->notNull('id')->orderBy('id desc')->find(); // holen Sie Kontakte, indem Sie die Beziehung verwenden: foreach($benutzer->kontakte as $kontakt) { echo $kontakt->id; } // oder wir können den anderen Weg gehen. $kontakt = new Kontakt(); // finde einen Kontakt $kontakt->find(); // holen Sie sich den Benutzer, indem Sie die Beziehung verwenden: echo $kontakt->user->name; // das ist der Benutzername
Ziemlich cool, oder?
Manchmal müssen Sie Ihrem Active Record etwas Einzigartiges anhängen, wie z.B. eine benutzerdefinierte Berechnung, die möglicherweise einfacher am Objekt angehängt werden kann, das dann an eine Vorlage übergeben wird.
setCustomData(string $field, mixed $value)
Sie hängen die benutzerdefinierten Daten mit der Methode setCustomData() an.
setCustomData()
$benutzer->setCustomData('page_view_count', $page_view_count);
Und dann beziehen Sie sich einfach darauf wie auf eine normale Objekteigenschaft.
echo $benutzer->page_view_count;
Ein weiteres super tolles Feature dieser Bibliothek sind Ereignisse. Ereignisse werden zu bestimmten Zeitpunkten basierend auf bestimmten von Ihnen aufgerufenen Methoden ausgelöst. Sie sind sehr hilfreich bei der Datenbearbeitung für Sie automatisch einzurichten.
onConstruct(ActiveRecord $ActiveRecord, array &config)
Dies ist sehr hilfreich, wenn Sie eine Standardverbindung oder so setzen müssen.
// index.php oder bootstrap.php Flight::register('db', 'PDO', [ 'sqlite:test.db' ]); // // // // User.php class User extends flight\ActiveRecord { protected function onConstruct(self $self, array &$config) { // don't forget the & reference // Sie könnten dies tun, um automatisch die Verbindung zu setzen $config['connection'] = Flight::db(); // oder so $self->transformAndPersistConnection(Flight::db()); // Sie können auch den Tabellennamen auf diese Weise festlegen. $config['table'] = 'users'; } }
beforeFind(ActiveRecord $ActiveRecord)
Das ist wahrscheinlich nur nützlich, wenn Sie jedes Mal eine Abfrage-Manipulation benötigen.
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function beforeFind(self $self) { // immer die ID >= 0 laufen lassen, wenn das Ihr Ding ist $self->gte('id', 0); } }
afterFind(ActiveRecord $ActiveRecord)
Dies ist wahrscheinlich nützlicher, wenn Sie jedes Mal, wenn dieser Datensatz geholt wird, etwas Logik ausführen müssen. Müssen Sie etwas entschlüsseln? Müssen Sie jedes Mal eine benutzerdefinierte Zählabfrage ausführen (nicht performant, aber egal)?
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function afterFind(self $self) { // etwas entschlüsseln $self->secret = yourDecryptFunction($self->secret, $some_key); // vielleicht etwas benutzerdefiniertes speichern wie eine Abfrage??? $self->setCustomData('view_count', $self->select('COUNT(*) count')->from('user_views')->eq('user_id', $self->id)['count']; } }
beforeFindAll(ActiveRecord $ActiveRecord)
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function beforeFindAll(self $self) { // immer die ID >= 0 laufen lassen, wenn das Ihr Ding ist $self->gte('id', 0); } }
afterFindAll(array<int,ActiveRecord> $results)
Ähnlich wie afterFind(), aber Sie können es auf alle Datensätze anwenden!
afterFind()
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function afterFindAll(array $results) { foreach($results as $self) { // mache etwas Cooleres wie afterFind() } } }
beforeInsert(ActiveRecord $ActiveRecord)
Wirklich hilfreich, wenn Sie jedes Mal einige Standardwerte setzen müssen.
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function beforeInsert(self $self) { // einige vernünftige Standardwerte setzen if(!$self->created_date) { $self->created_date = gmdate('Y-m-d'); } if(!$self->password) { $self->password = password_hash((string) microtime(true)); } } }
afterInsert(ActiveRecord $ActiveRecord)
Vielleicht haben Sie einen Anwendungsfall zum Ändern von Daten nach dem Einfügen?
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function afterInsert(self $self) { // Sie tun, was Sie für richtig halten Flight::cache()->set('most_recent_insert_id', $self->id); // oder was auch immer.... } }
beforeUpdate(ActiveRecord $ActiveRecord)
Wirklich hilfreich, wenn Sie jedes Mal einige Standardwerte beim Update setzen müssen.
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function beforeInsert(self $self) { // einige vernünftige Standardwerte setzen if(!$self->updated_date) { $self->updated_date = gmdate('Y-m-d'); } } }
afterUpdate(ActiveRecord $ActiveRecord)
Vielleicht haben Sie einen Anwendungsfall zum Ändern von Daten nach dem Update?
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function afterInsert(self $self) { // Sie tun, was Sie für richtig halten Flight::cache()->set('most_recently_updated_user_id', $self->id); // oder was auch immer.... } }
beforeSave(ActiveRecord $ActiveRecord)/afterSave(ActiveRecord $ActiveRecord)
Dies ist nützlich, wenn Sie Ereignisse sowohl bei Inserts als auch bei Updates wünschen. Ich erspare Ihnen die lange Erklärung, aber ich bin sicher, Sie können erraten, was es ist.
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function beforeSave(self $self) { $self->last_updated = gmdate('Y-m-d H:i:s'); } }
beforeDelete(ActiveRecord $ActiveRecord)/afterDelete(ActiveRecord $ActiveRecord)
Nicht sicher, was Sie hier tun möchten, aber keine Urteile hier! Ran an die Arbeit!
class User extends flight\ActiveRecord { public function __construct($datenbank_verbindung) { parent::__construct($datenbank_verbindung, 'users'); } protected function beforeDelete(self $self) { echo 'Er war ein tapferer Soldat... :cry-face:'; } }
Wenn Sie diese Bibliothek verwenden, können Sie die Datenbankverbindung auf verschiedene Arten festlegen. Sie können die Verbindung im Konstruktor festlegen, Sie können sie über eine Konfigurationsvariable $config['connection'] festlegen oder Sie können sie über setDatabaseConnection() setzen (ab Version 0.4.1).
$config['connection']
setDatabaseConnection()
$pdo_verbindung = new PDO('sqlite:test.db'); // zum Beispiel $benutzer = new Benutzer($pdo_verbindung); // oder $benutzer = new Benutzer(null, [ 'connection' => $pdo_verbindung ]); // oder $benutzer = new Benutzer(); $benutzer->setDatabaseConnection($pdo_verbindung);
Wenn Sie die Datenbankverbindung aktualisieren müssen, z. B. wenn Sie ein lang laufendes CLI-Skript ausführen und die Verbindung alle paar Minuten aktualisieren müssen, können Sie die Verbindung mit $your_record->setDatabaseConnection($pdo_verbindung) erneut setzen.
$your_record->setDatabaseConnection($pdo_verbindung)
Bitte tun Sie das. :D
Wenn Sie beitragen, stellen Sie sicher, dass Sie composer test-coverage ausführen, um eine Testabdeckung von 100 % aufrechtzuerhalten (dies ist keine echte Unit-Testabdeckung, sondern eher eine Integrationstestabdeckung).
composer test-coverage
Stellen Sie außerdem sicher, dass Sie composer beautify und composer phpcs ausführen, um Fehler in der Formatierung zu beheben.
composer beautify
composer phpcs
MIT
Latte ist ein voll ausgestatteter Template-Engine, der sehr einfach zu bedienen ist und sich näher an einer PHP-Syntax anfühlt als Twig oder Smarty. Es ist auch sehr einfach zu erweitern und eigene Filter und Funktionen hinzuzufügen.
Installieren Sie mit Composer.
composer require latte/latte
Es gibt einige grundlegende Konfigurationsoptionen, um loszulegen. Weitere Informationen dazu finden Sie in der Latte-Dokumentation.
use Latte\Engine as LatteEngine; require 'vendor/autoload.php'; $app = Flight::app(); $app->register('latte', LatteEngine::class, [], function(LatteEngine $latte) use ($app) { // Hier speichert Latte Ihre Templates, um die Geschwindigkeit zu erhöhen // Eine interessante Sache an Latte ist, dass es automatisch Ihren Cache aktualisiert, // wenn Sie Änderungen an Ihren Templates vornehmen! $latte->setTempDirectory(__DIR__ . '/../cache/'); // Geben Sie Latte an, wo sich das Stammverzeichnis für Ihre Ansichten befinden wird. // $app->get('flight.views.path') ist in der config.php-Datei festgelegt // Sie könnten auch einfach etwas wie `__DIR__ . '/../views/'` tun $latte->setLoader(new \Latte\Loaders\FileLoader($app->get('flight.views.path'))); });
Hier ist ein einfaches Beispiel für eine Layoutdatei. Diese Datei wird verwendet, um alle Ihre anderen Ansichten zu umschließen.
<!-- app/views/layout.latte --> <!doctype html> <html lang="de"> <head> <title>{$title ? $title . ' - '}Meine App</title> <link rel="stylesheet" href="style.css"> </head> <body> <header> <nav> <!-- Ihre Navigations-Elemente hier --> </nav> </header> <div id="content"> <!-- Hier liegt die Magie --> {block content}{/block} </div> <div id="footer"> © Urheberrecht </div> </body> </html>
Und jetzt haben wir Ihre Datei, die in diesem Inhaltsblock gerendert werden soll:
<!-- app/views/home.latte --> <!-- Dies sagt Latte, dass diese Datei "innerhalb" der layout.latte-Datei ist --> {extends layout.latte} <!-- Dies ist der Inhalt, der innerhalb des Layouts im Inhaltsblock gerendert wird --> {block content} <h1>Startseite</h1> <p>Willkommen bei meiner App!</p> {/block}
Dann, wenn Sie dies in Ihrer Funktion oder Ihrem Controller rendern möchten, würden Sie etwas Ähnliches tun:
// einfache Route Flight::route('/', function () { Flight::latte()->render('home.latte', [ 'title' => 'Startseite' ]); }); // oder wenn Sie einen Controller verwenden Flight::route('/', [HomeController::class, 'index']); // HomeController.php class HomeController { public function index() { Flight::latte()->render('home.latte', [ 'title' => 'Startseite' ]); } }
Schauen Sie in der Latte-Dokumentation nach weiteren Informationen darüber, wie Sie Latte optimal nutzen können!
Flight ist unglaublich erweiterbar. Es gibt eine Anzahl von Plugins, die verwendet werden können, um Funktionalitäten zu Ihrer Flight-Anwendung hinzuzufügen. Einige werden offiziell vom Flight-Team unterstützt, andere sind Micro/Lite-Bibliotheken, um Ihnen den Einstieg zu erleichtern.
Authentifizierung und Berechtigung sind entscheidend für jede Anwendung, die Steuerungen erfordert, um festzulegen, wer auf was zugreifen kann.
Der Zwischenspeicher ist eine großartige Möglichkeit, um Ihre Anwendung zu beschleunigen. Es gibt eine Anzahl von Zwischenspeicher-Bibliotheken, die mit Flight verwendet werden können.
CLI-Anwendungen sind eine großartige Möglichkeit, mit Ihrer Anwendung zu interagieren. Sie können sie verwenden, um Controller zu generieren, alle Routen anzuzeigen und mehr.
Cookies sind eine großartige Möglichkeit, kleine Datenstücke auf der Clientseite zu speichern. Sie können verwendet werden, um Benutzereinstellungen, Anwendungseinstellungen und mehr zu speichern.
Debuggen ist entscheidend, wenn Sie in Ihrer lokalen Umgebung entwickeln. Es gibt ein paar Plugins, die Ihr Debugging-Erlebnis verbessern können.
Datenbanken sind das Herzstück vieler Anwendungen. So speichern und abrufen Sie Daten. Einige Datenbank-Bibliotheken sind einfach Wrapper, um Abfragen zu schreiben, während andere vollständige ORMs sind.
Verschlüsselung ist entscheidend für jede Anwendung, die sensible Daten speichert. Das Verschlüsseln und Entschlüsseln der Daten ist nicht besonders schwierig, aber das ordnungsgemäße Speichern des Verschlüsselungsschlüssels kann schwierig sein. Das Wichtigste ist, den Verschlüsselungsschlüssel niemals in einem öffentlichen Verzeichnis zu speichern oder ihn in Ihr Code-Repository zu übernehmen.
Sitzungen sind für APIs nicht wirklich nützlich, aber für den Aufbau einer Webanwendung können Sitzungen entscheidend sein, um den Zustand und die Anmeldeinformationen aufrechtzuerhalten.
Vorlagen sind elementar für jede Webanwendung mit einer Benutzeroberfläche. Es gibt eine Anzahl von Template-Engines, die mit Flight verwendet werden können.
Haben Sie ein Plugin, das Sie teilen möchten? Reichen Sie einen Pull-Request ein, um es der Liste hinzuzufügen!
Wir haben versucht, herauszufinden, was wir von den verschiedenen Arten von Medien im Internet rund um Flight finden können. Siehe unten für verschiedene Ressourcen, die Sie nutzen können, um mehr über Flight zu erfahren.
Sie haben zwei Möglichkeiten, um mit Flight zu beginnen:
Obwohl diese nicht offiziell vom Flight-Team gesponsert werden, könnten sie Ihnen Ideen geben, wie Sie Ihre eigenen Projekte strukturieren, die mit Flight erstellt wurden!
Wenn Sie ein Projekt haben, das Sie teilen möchten, reichen Sie bitte einen Pull-Request ein, um es zu dieser Liste hinzuzufügen!
Stellen Sie sicher, dass PHP auf Ihrem System installiert ist. Wenn nicht, klicken Sie hier, um Anweisungen zur Installation für Ihr System zu erhalten.
Wenn Sie Composer verwenden, können Sie folgenden Befehl ausführen:
ODER Sie können die Dateien hier herunterladen und direkt in Ihr Webverzeichnis extrahieren.
Dies ist bei weitem der einfachste Weg, um loszulegen. Sie können den integrierten Server verwenden, um Ihre Anwendung auszuführen und sogar SQLite für eine Datenbank zu verwenden (solange sqlite3 auf Ihrem System installiert ist) und praktisch nichts benötigen! Führen Sie nach der Installation von PHP einfach den folgenden Befehl aus:
php -S localhost:8000
Öffnen Sie dann Ihren Browser und gehen Sie zu http://localhost:8000.
http://localhost:8000
Wenn Sie das Dokumentenverzeichnis Ihres Projekts in ein anderes Verzeichnis ändern möchten (Beispiel: Ihr Projekt ist ~/myproject, aber Ihr Dokumentenstamm ist ~/myproject/public/), können Sie nach dem Wechsel in das Verzeichnis ~/myproject den folgenden Befehl ausführen:
~/myproject
~/myproject/public/
php -S localhost:8000 -t public/
Stellen Sie sicher, dass Apache bereits auf Ihrem System installiert ist. Wenn nicht, suchen Sie bei Google nach Anweisungen zur Installation von Apache auf Ihrem System.
Hinweis: Wenn Sie Flight in einem Unterverzeichnis verwenden müssen, fügen Sie die Zeile RewriteBase /subdir/ direkt nach RewriteEngine On hinzu. Hinweis: Wenn Sie alle Serverdateien schützen möchten, z. B. eine Datenbank- oder Umgebungsdatei. Fügen Sie dies in Ihre .htaccess-Datei ein:
Hinweis: Wenn Sie Flight in einem Unterverzeichnis verwenden müssen, fügen Sie die Zeile RewriteBase /subdir/ direkt nach RewriteEngine On hinzu.
Hinweis: Wenn Sie alle Serverdateien schützen möchten, z. B. eine Datenbank- oder Umgebungsdatei. Fügen Sie dies in Ihre .htaccess-Datei ein:
Stellen Sie sicher, dass Nginx bereits auf Ihrem System installiert ist. Wenn nicht, suchen Sie bei Google nach Anweisungen zur Installation von Nginx auf Ihrem System.
Fügen Sie für Nginx Folgendes zur Serverdeklaration hinzu:
<?php // Wenn Sie Composer verwenden, erfordern Sie den Autoloader. require 'vendor/autoload.php'; // Wenn Sie Composer nicht verwenden, laden Sie das Framework direkt // require 'flight/Flight.php'; // Definieren Sie dann eine Route und weisen Sie eine Funktion zur Behandlung der Anfrage zu. Flight::route('/', function () { echo 'Hallo Welt!'; }); // Starten Sie das Framework schließlich. Flight::start();
Wenn Sie bereits über php auf Ihrem System verfügen, überspringen Sie diese Anweisungen und wechseln Sie zum Download-Abschnitt
php
Sicher! Hier sind die Anweisungen zur Installation von PHP auf macOS, Windows 10/11, Ubuntu und Rocky Linux. Ich werde auch Details darüber enthalten, wie verschiedene Versionen von PHP installiert werden.
Homebrew installieren (wenn nicht bereits installiert):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
PHP installieren:
brew install php
brew tap shivammathur/php brew install shivammathur/php/php@8.1
Zwischen PHP-Versionen wechseln:
brew unlink php brew link --overwrite --force php@8.1
php -v
PHP herunterladen:
PHP extrahieren:
C:\php
PHP zum System-PATH hinzufügen:
PHP konfigurieren:
php.ini-development
php.ini
extension_dir
PHP-Installation überprüfen:
Wiederholen Sie die obigen Schritte für jede Version und platzieren Sie sie jeweils in einem separaten Verzeichnis (z. B. C:\php7, C:\php8).
C:\php7
C:\php8
Zwischen den Versionen wechseln, indem Sie die System-PATH-Variable anpassen, um auf das gewünschte Versionsverzeichnis zu verweisen.
Paketlisten aktualisieren:
sudo apt update
sudo apt install php
sudo apt install php8.1
Zusätzliche Module installieren (optional):
sudo apt install php8.1-mysql
update-alternatives
sudo update-alternatives --set php /usr/bin/php8.1
Installierte Version überprüfen:
EPEL-Repository aktivieren:
sudo dnf install epel-release
Remi-Repository installieren:
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm sudo dnf module reset php
sudo dnf install php
sudo dnf module install php:remi-7.4
dnf module
sudo dnf module reset php sudo dnf module enable php:remi-8.0 sudo dnf install php
Überprüfen Sie die installierte Version: