Learn

Erfahren Sie mehr über Flight

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.

Wichtige Framework-Konzepte

Warum ein Framework?

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.

Flight im Vergleich zu anderen Frameworks

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.

Kernthemen

Autoloading

Lernen Sie, wie Sie Ihre eigenen Klassen in Ihrer Anwendung automatisch laden.

Routing

Lernen Sie, wie Sie Routen für Ihre Webanwendung verwalten. Dies umfasst auch das Gruppieren von Routen, Routenparameter und Middleware.

Middleware

Lernen Sie, wie Sie Middleware verwenden, um Anfragen und Antworten in Ihrer Anwendung zu filtern.

Anfragen

Lernen Sie, wie Sie Anfragen und Antworten in Ihrer Anwendung verarbeiten.

Antworten

Lernen Sie, wie Sie Antworten an Ihre Benutzer senden.

HTML-Templates

Lernen Sie, wie Sie den integrierten View-Engine verwenden, um Ihre HTML-Templates zu rendern.

Sicherheit

Lernen Sie, wie Sie Ihre Anwendung vor üblichen Sicherheitsbedrohungen schützen.

Konfiguration

Lernen Sie, wie Sie das Framework für Ihre Anwendung konfigurieren.

Flight erweitern

Lernen Sie, wie Sie das Framework erweitern, um Ihre eigenen Methoden und Klassen hinzuzufügen.

Ereignisse und Filterung

Lernen Sie, wie Sie das Ereignissystem verwenden, um Hooks zu Ihren Methoden und internen Framework-Methoden hinzuzufügen.

Dependency Injection Container

Lernen Sie, wie Sie Dependency Injection Container (DIC) verwenden, um die Abhängigkeiten Ihrer Anwendung zu verwalten.

Framework-API

Erfahren Sie mehr über die Kernmethoden des Frameworks.

Migration auf v3

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.

Problembehandlung

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.

Learn/stopping

Anhalten

Sie können das Framework jederzeit durch Aufrufen der halt Methode stoppen:

Flight::halt();

Sie können auch einen optionalen HTTP-Statuscode und eine Nachricht angeben:

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:

Flight::stop();

Learn/errorhandling

Fehlerbehandlung

Fehler und Ausnahmen

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.

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);

Nicht gefunden

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.

Sie können dieses Verhalten nach Ihren eigenen Bedürfnissen überschreiben:

Flight::map('notFound', function () {
  // Nicht gefunden behandeln
});

Learn/flight_vs_laravel

Flight vs Laravel

Was ist Laravel?

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.

Vor- und Nachteile im Vergleich zu Flight

Nachteile im Vergleich zu Flight

Learn/migrating_to_v3

Migration zu v3

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.

Verhalten beim Output-Puffer (3.5.0)

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.

Wo Sie Probleme haben könnten

// 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>';
});

Aktivieren des v2-Rendering-Verhaltens

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.

// 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 

Dispatcher-Änderungen (3.7.0)

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.

Änderungen an halt() stop() redirect() und error() (3.10.0)

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.

Learn/configuration

Konfiguration

Sie können bestimmte Verhaltensweisen von Flight anpassen, indem Sie Konfigurationswerte über die set-Methode festlegen.

Flight::set('flight.log_errors', true);

Verfügbare Konfigurationseinstellungen

Im Folgenden finden Sie eine Liste aller verfügbaren Konfigurationseinstellungen:

Loader-Konfiguration

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;

Variablen

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.

Flight::set('flight.log_errors', true);

Fehlerbehandlung

Fehler und Ausnahmen

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.

Sie können dieses Verhalten für Ihre eigenen Bedürfnisse ü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);

Nicht gefunden

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.

Sie können dieses Verhalten für Ihre eigenen Bedürfnisse überschreiben:

Flight::map('notFound', function () {
  // Nicht gefunden behandeln
});

Learn/security

Sicherheit

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.

Header

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.

Manuell hinzufügen

Sie können diese Header manuell hinzufügen, indem Sie die header-Methode auf dem Flight\Response-Objekt verwenden.

// 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.

Als Filter hinzufügen

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=()');
});

Als Middleware hinzufügen

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)

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.

Einrichtung

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>

Verwendung von Latte

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.

<form method="post">
    {csrf()}
    <!-- andere Formularfelder -->
</form>

Kurz und knapp, richtig?

Überprüfen des CSRF-Tokens

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)

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: &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;

// Wenn Sie beispielsweise Latte als Ihre View-Klasse registriert haben, wird dies automatisch auch escapen.
Flight::view()->render('Vorlage', ['name' => $name]);

SQL-Injection

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.

// 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.

CORS

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.

// 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' ]);

Fazit

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.

Learn/overriding

Überschreiben

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:

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.

Learn/routing

Routen

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.

Rückruffunktionen/Funktionen

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');

Klassen

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');

Abhängigkeitsinjektion über DIC (Dependency Injection Container)

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();

Methodenrouten

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();

Reguläre Ausdrücke

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.

Benannte Parameter

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. :'(

Optionale Parameter

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.

Platzhalter

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
});

Weitergabe

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
});

Routenalias

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.

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

Routeninformationen

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);

Routengruppen

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:

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
    });
  });
});

Gruppierung mit Objektkontext

Sie können die Routengruppierung immer noch mit dem Engine-Objekt auf folgende Weise verwenden:

$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
  });
});

Streaming

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.

Anmerkung: Das Streamen von Antworten ist nur verfügbar, wenn Sie flight.v2.output_buffering auf false gesetzt haben.

Streamen mit manuellen Headern

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.

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();

Streamen mit Headern

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
]);

Learn/flight_vs_symfony

Flight vs Symfony

Was ist Symfony?

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.

Vor- und Nachteile im Vergleich zu Flight

Vorteile im Vergleich zu Flight

Nachteile im Vergleich zu Flight

Learn/flight_vs_another_framework

Vergleich von Flight mit einem anderen Framework

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.

Laravel

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

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

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

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.

Learn/variables

Variablen

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 zu überprüfen, ob eine Variable festgelegt wurde, können Sie Folgendes tun:

if (Flight::has('id')) {
  // Mach etwas
}

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.

Flight::set('flight.log_errors', true);

Learn/dependency_injection_container

Dependency Injection Container

Einführung

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.

Grundbeispiel

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.

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!

PSR-11

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!

Eigener DIC-Handler

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.

Engine-Instanz

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');
    }
}

Hinzufügen anderer Klassen

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');

Learn/middleware

# 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:

Middleware-Klassen

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

Behandlung von Middleware-Fehlern

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:

  1. Sie können false aus der Middleware-Funktion zurückgeben, und Flight gibt automatisch einen 403 Forbidden error zurück, aber ohne Anpassung.
  2. Sie können den Benutzer mit Flight::redirect() auf eine Login-Seite umleiten.
  3. Sie können einen benutzerdefinierten Fehler innerhalb der Middleware erstellen und die Ausführung der Route stoppen.

Grundlegendes Beispiel

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
    }
}

Umleitungsbeispiel

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;
        }
    }
}

Benutzerdefiniertes Fehlerbeispiel

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.']);
        }
    }
}

Gruppierung von Middleware

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() ]);

Learn/filtering

Filtern

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:

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.

Learn/requests

Anfragen

Flight kapselt die HTTP-Anfrage in ein einzelnes Objekt, das aufgerufen werden kann durch:

$request = Flight::request();

Typische Anwendungsfälle

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.

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
});

Eigenschaften des Anfrageobjekts

Das Anfrageobjekt bietet die folgenden Eigenschaften:

Sie können auf die Eigenschaften query, data, cookies und files als Arrays oder Objekte zugreifen.

Um einen Abfragezeichenfolgenparameter zu erhalten, können Sie tun:

$id = Flight::request()->query['id'];

Oder Sie können tun:

$id = Flight::request()->query->id;

RAW Anfrageinhalt

Um den rohen HTTP-Anfrageinhalt zu erhalten, beispielsweise bei PUT-Anfragen, können Sie tun:

$body = Flight::request()->getBody();

JSON-Eingabe

Wenn Sie eine Anfrage mit dem Typ application/json und den Daten {"id": 123} senden, ist es über die data-Eigenschaft verfügbar:

$id = Flight::request()->data->id;

$_GET

Sie können auf das $_GET-Array über die query-Eigenschaft zugreifen:

$id = Flight::request()->query['id'];

$_POST

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'];

$_SERVER

Es gibt eine Abkürzung, um auf das $_SERVER-Array über die getVar()-Methode zuzugreifen:


$host = Flight::request()->getVar['HTTP_HOST'];

Hochgeladene Dateien über $_FILES zugreifen

Sie können auf hochgeladene Dateien über die files-Eigenschaft zugreifen:

$uploadedFile = Flight::request()->files['myFile'];

Verarbeitung von Datei-Uploads

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.

Anfrage-Header

Sie können auf Anfrage-Header mithilfe der getHeader()- oder getHeaders()-Methode zugreifen:


// 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();

Anfrageinhalt

Sie können auf den rohen Anfrageinhalt über die getBody()-Methode zugreifen:

$body = Flight::request()->getBody();

Anfrage-Methode

Sie können auf die Anfrage-Methode über die method-Eigenschaft oder die getMethod()-Methode zugreifen:

$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.

Anfrage-URLs

Es gibt eine Reihe von Hilfsmethoden, um Teile einer URL zu Ihrem Vorteil zusammenzufügen.

Vollständige URL

Sie können die vollständige Anforderungs-URL über die getFullUrl()-Methode abrufen:

$url = Flight::request()->getFullUrl();
// https://example.com/some/path?foo=bar

Basis-URL

Sie können die Basis-URL über die getBaseUrl()-Methode abrufen:

$url = Flight::request()->getBaseUrl();
// Hinweis, kein abschließender Schrägstrich.
// https://example.com

Abfrageanalyse

Sie können eine URL an die parseQuery()-Methode übergeben, um die Abfragezeichenfolge in ein assoziatives Array zu analysieren:

$query = Flight::request()->parseQuery('https://example.com/some/path?foo=bar');
// ['foo' => 'bar']

Learn/frameworkmethods

Methoden des Frameworks

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.

Kernmethoden

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.

Erweiterbare Methoden

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.

Learn/api

Kernmethoden

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

Erweiterbare Methoden

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.

Learn/why_frameworks

Warum ein Framework?

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.

Gründe für die Verwendung eines 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.

Was ist Routing?

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.

Es könnte etwa so funktionieren:

Und warum ist das wichtig?

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:

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.

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!

Anfragen und Antworten

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.

Anfragen

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.

Antworten

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.

Learn/httpcaching

HTTP-Caching

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.

Zuletzt geändert

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.

Flight::route('/nachrichten', function () {
  Flight::lastModified(1234567890);
  echo 'Dieser Inhalt wird zwischengespeichert sein.';
});

ETag

Das Caching von ETag ist ähnlich wie Last-Modified, außer dass Sie eine beliebige ID für die Ressource angeben können:

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.

Learn/responses

Antworten

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.

Senden einer einfachen Antwort

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.


// 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.


// 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();
});

Statuscodes

Sie können den Statuscode der Antwort durch Verwendung der status-Methode festlegen:

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

Festlegen eines Antwortbodys

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.

Flight::route('/', function() {
    Flight::response()->write("Hallo, Welt!");
});

// dasselbe wie

Flight::route('/', function() {
    echo "Hallo, Welt!";
});

Löschen eines Antwortbodys

Wenn Sie den Antwortbody löschen möchten, können Sie die clearBody-Methode verwenden:

Flight::route('/', function() {
    if($someCondition) {
        Flight::response()->write("Hallo, Welt!");
    } else {
        Flight::response()->clearBody();
    }
});

Ausführen eines Callbacks auf dem Antwortbody

Sie können einen Callback auf dem Antwortbody ausführen, indem Sie die addResponseBodyCallback-Methode verwenden:

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.

Hinweis: Routen-Callbacks funktionieren nicht, wenn Sie die Konfigurationsoption flight.v2.output_buffering verwenden.

Spezifisches Routen-Callback

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);
    });
});

Middleware-Option

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() ]);

Festlegen eines Antwort-Headers

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!";
});

JSON

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]);

JSON mit Statuscode

Sie können auch als zweites Argument einen Statuscode übergeben:

Flight::json(['id' => 123], 201);

JSON mit Pretty Print

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::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);

JSON und Ausführung stoppen (v3.10.0)

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.

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
});

JSONP

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:

my_func({"id":123});

Wenn Sie keinen Abfrageparameter angeben, wird standardmäßig jsonp verwendet.

Weiterleitung zu einer anderen URL

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);

Beenden

Sie können das Framework jederzeit anhalten, indem Sie die halt-Methode aufrufen:

Flight::halt();

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:

Flight::stop();

Löschen von Antwortdaten

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.

Flight::response()->clear();

Nur Antwortbody löschen

Wenn Sie nur den Antwortbody löschen möchten, können Sie die clearBody()-Methode verwenden:

// Dies behält weiterhin alle Header bei, die für das response() Objekt festgelegt wurden.
Flight::response()->clearBody();

HTTP-Caching

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.

Caching auf Routenebene

Wenn Sie Ihre gesamte Antwort zwischenspeichern möchten, können Sie die cache()-Methode verwenden und die Zeit zum Zwischenspeichern angeben.


// 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.';
});

Zuletzt geändert

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

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.

Herunterladen einer Datei

Es gibt eine Hilfsmethode zum Herunterladen einer Datei. Sie können die download-Methode und den Dateipfad verwenden.

Flight::route('/download', function () {
  Flight::download('/pfad/zur/datei.txt');
});

Learn/frameworkinstance

Framework-Instanz

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.

Learn/redirects

Weiterleitungen

Sie können die aktuelle Anfrage umleiten, indem Sie die redirect Methode verwenden und eine neue URL übergeben:

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);

Learn/views

Ansichten

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:

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:

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:

Flight::render('hello');

Beachten Sie, dass beim Festlegen des Namens des Templates in der Render-Methode die Dateierweiterung .php ausgelassen werden kann.

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:

Flight::set('flight.views.path', '/pfad/zu/ansichten');

Layouts

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:

Flight::render('layout', ['title' => 'Startseite']);

Wenn die Template-Dateien wie folgt aussehen:

header.php:

<h1><?= $heading ?></h1>

body.php:

<div><?= $body ?></div>

layout.php:

<html>
  <head>
    <title><?= $title ?></title>
  </head>
  <body>
    <?= $headerContent ?>
    <?= $bodyContent ?>
  </body>
</html>

Die Ausgabe wäre:

<html>
  <head>
    <title>Startseite</title>
  </head>
  <body>
    <h1>Hallo</h1>
    <div>Welt</div>
  </body>
</html>

Individuelle Ansichten

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);
});

Learn/templates

HTML-Ansichten und Vorlagen

Flight bietet standardmäßig einige grundlegende Vorlagenfunktionalitäten.

Wenn Sie komplexere Vorlagenanforderungen haben, beachten Sie die Smarty- und Latte-Beispiele im Abschnitt Benutzerdefinierte Ansichten.

Standardansichtsmaschine

Um eine Ansichtsvorlage anzuzeigen, rufen Sie die Methode render mit dem Namen der Vorlagendatei und optionalen Vorlagendaten auf:

Flight::render('hello.php', ['name' => 'Bob']);

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:

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 steht nun in allen Ihren Ansichten zur Verfügung. Sie können also einfach Folgendes tun:

Flight::render('hello');

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');

Layouts

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.

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:

Flight::render('layout', ['title' => 'Startseite']);

Wenn die Vorlagendateien wie folgt aussehen:

header.php:

<h1><?= $heading ?></h1>

body.php:

<div><?= $body ?></div>

layout.php:

<html>
  <head>
    <title><?= $title ?></title>
  </head>
  <body>
    <?= $headerContent ?>
    <?= $bodyContent ?>
  </body>
</html>

Die Ausgabe wäre:

<html>
  <head>
    <title>Startseite</title>
  </head>
  <body>
    <h1>Hallo</h1>
    <div>Welt</div>
  </body>
</html>

Benutzerdefinierte Ansichtsmaschinen

Flight ermöglicht es Ihnen, die Standardansichtsmaschine einfach durch Registrierung Ihrer eigenen Ansichtsklasse auszutauschen.

Smarty

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:

Flight::map('render', function(string $template, array $data): void {
  Flight::view()->assign($data);
  Flight::view()->display($template);
});

Latte

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);
});

Learn/flight_vs_fat_free

Flight vs Fat-Free

Was ist Fat-Free?

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.

Vorzüge im Vergleich zu Flight

Nachteile im Vergleich zu Flight

Learn/extending

Erweitern

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.

Methoden zuordnen

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.

Klassen registrieren

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.

Überschreiben von Framework-Methoden

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::map('notFound', function() {
  // Benutzerdefinierte 404-Seite anzeigen
  include 'errors/404.html';
});

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.

Learn/json

# 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:

Flight::jsonp(['id' => 123], 'q');

Wenn Sie also eine GET-Anfrage mit ?q=my_func stellen, sollten Sie die Ausgabe erhalten:

my_func({"id":123});

Wenn Sie keinen Abfrageparameter Namen angeben, wird standardmäßig jsonp verwendet.

Learn/flight_vs_slim

Flug vs. Schlank

Was ist Schlank?

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.

Vorteile im Vergleich zu Flug

Nachteile im Vergleich zu Flug

Learn/autoloading

Autoloading

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.

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.

Grundbeispiel

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
    }
}

Namensräume

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/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
    }
}

Unterstriche in Klassennamen

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.


/**
 * 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
    }
}

Learn/troubleshooting

Fehlerbehebung

Diese Seite hilft Ihnen bei der Fehlerbehebung von häufig auftretenden Problemen, auf die Sie bei der Verwendung von Flight stoßen könnten.

Häufige Probleme

404 Nicht gefunden oder unerwartetes Routenverhalten

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.

Klasse nicht gefunden (Autoloading funktioniert nicht)

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.

Falscher Dateiname

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.

Falscher Namespace

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() nicht definiert

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.

// Fügen Sie einen Pfad zum Autoloader hinzu
Flight::path(__DIR__.'/../');

Install

Installation

Lade die Dateien herunter.

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.

Konfigurieren Sie Ihren Webserver.

Apache

Für Apache bearbeiten Sie Ihre .htaccess-Datei wie folgt:

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:

RewriteEngine On
RewriteRule ^(.*)$ index.php

Nginx

Für Nginx fügen Sie Folgendes zu Ihrer Serverdeklaration hinzu:

server {
  location / {
    try_files $uri $uri/ /index.php;
  }
}

Erstellen Sie Ihre index.php-Datei.

<?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();

License

Die MIT-Lizenz (MIT)

Urheberrecht © 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.

About

Was ist Flight?

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.

Schnellstart

<?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!

Skelett/Grundgerüstanwendung

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.

Community

Wir sind im Matrix-Chat mit uns unter #flight-php-framework:matrix.org.

Beitragende

Es gibt zwei Möglichkeiten, wie Sie zu Flight beitragen können:

  1. Sie können zum Kernframework beitragen, indem Sie das Kern-Repository besuchen.
  2. Sie können zur Dokumentation beitragen. Diese Dokumentationswebsite wird auf Github gehostet. Wenn Sie einen Fehler bemerken oder etwas besser ausarbeiten möchten, können Sie es gerne korrigieren und einen Pull-Request einreichen! Wir versuchen, auf dem neuesten Stand zu bleiben, aber Aktualisierungen und Sprachübersetzungen sind willkommen.

Anforderungen

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.

Lizenz

Flight wird unter der MIT Lizenz veröffentlicht.

Awesome-plugins/php_cookie

Cookies

overclokk/cookie ist eine einfache Bibliothek zum Verwalten von Cookies in Ihrer App.

Installation

Die Installation ist mit Composer einfach.

composer require overclokk/cookie

Verwendung

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');
        }
    }
}

Awesome-plugins/php_encryption

PHP-Verschlüsselung

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.

Installation

Die Installation ist einfach mit Composer.

composer require defuse/php-encryption

Einrichtung

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.

Verwendung

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;
});

Awesome-plugins/php_file_cache

Wruczek/PHP-File-Cache

Leichte, einfache und eigenständige PHP-In-File-Caching-Klasse

Vorteile

Klicken Sie hier, um den Code anzuzeigen.

Installation

Installation über Composer:

composer require wruczek/php-file-cache

Verwendung

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
}

Dokumentation

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.

Awesome-plugins/permissions

FlightPHP/Berechtigungen

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.

Installation

Führen Sie composer require flightphp/permissions aus und los geht's!

Verwendung

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.

Grundbeispiel

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
        }
    }
}

Abhängigkeiten injizieren

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.

Closures

$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
    }
}

Klassen

namespace MeinApp;

class Berechtigungen {

    public function bestellung(string $current_role, MyDependency $MyDependency = null) {
        // ... code
    }
}

Verknüpfung zum Setzen von Berechtigungen mit Klassen

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:

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!');
        }
    }
}

Zwischenspeicherung

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

Awesome-plugins/index

Tolle Plugins

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

Caching ist ein großartiger Weg, um Ihre Anwendung zu beschleunigen. Es gibt einige Caching-Bibliotheken, die mit Flight verwendet werden können.

Debugging

Debugging ist entscheidend, wenn Sie in Ihrer lokalen Umgebung entwickeln. Es gibt einige Plugins, die Ihr Debugging-Erlebnis verbessern können.

Datenbanken

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.

Sitzung

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.

Templating

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.

Mitwirken

Haben Sie ein Plugin, das Sie teilen möchten? Senden Sie einen Pull-Request, um es der Liste hinzuzufügen!

Awesome-plugins/pdo_wrapper

PdoWrapper PDO Helper Klasse

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 der PDO Helper Klasse

// 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
    ]
]);

Verwendung

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;
}

Hinweis zur IN() Syntax

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 ]);

Vollständiges Beispiel

// 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();

});

Awesome-plugins/session

Geist/Session

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.

Klicken Sie hier, um den Code anzuzeigen.

Installation

Installation mit Composer.

composer require geist/session

Grundkonfiguration

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.

Einfaches Beispiel

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');
    }
});

Komplexeres Beispiel

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
            ]
        ]);
    }
);

Hilfe! Meine Sitzungsdaten bleiben nicht bestehen!

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.

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.


$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.

Dokumentation

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.

Awesome-plugins/runway

Startbahn

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.

Installation

Mit Composer installieren.

composer require flightphp/startbahn

Grundkonfiguration

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.

Verwendung

Startbahn hat mehrere Befehle, die Sie verwenden können, um Ihre Flight-Anwendung zu verwalten. Es gibt zwei einfache Möglichkeiten, Startbahn zu verwenden.

  1. Wenn Sie das Grundgerüstprojekt verwenden, können Sie php startbahn [Befehl] im Stammverzeichnis Ihres Projekts ausführen.
  2. Wenn Sie Startbahn als über Composer installiertes Paket verwenden, können Sie vendor/bin/startbahn [Befehl] im Stammverzeichnis Ihres Projekts ausführen.

Für jeden Befehl können Sie die --help-Flagge übergeben, um weitere Informationen zur Verwendung des Befehls zu erhalten.

php startbahn routes --help

Hier sind ein paar Beispiele:

Einen Controller generieren

Basierend auf der Konfiguration in Ihrer .runway.json-Datei wird der Standardort einen Controller für Sie im app/controllers/ Verzeichnis generieren.

php startbahn make:controller MeinController

Einen Aktiven Datensatz-Model generieren

Basierend auf der Konfiguration in Ihrer .runway.json-Datei wird der Standardort einen Controller für Sie im app/records/ Verzeichnis generieren.

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:

<?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');
    }
}

Alle Routen anzeigen

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.

Anpassen von Startbahn

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.

Um einen Befehl zu erstellen, erweitern Sie einfach die Klasse AbstractBaseCommand und implementieren Sie mindestens eine __construct-Methode und eine ausführen-Methode.

<?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!

Awesome-plugins/tracy_extensions

Tracy Flight Panel Erweiterungen

Dies ist eine Sammlung von Erweiterungen, um die Arbeit mit Flight etwas komfortabler zu gestalten.

Dies ist das Panel

Flight-Leiste

Und jedes Panel zeigt sehr hilfreiche Informationen über Ihre Anwendung!

Flight-Daten Flight-Datenbank Flight-Anfrage

Klicke hier, um den Code anzusehen.

Installation

Führen Sie composer require flightphp/tracy-extensions --dev aus und los geht's!

Konfiguration

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();

Zusätzliche Konfiguration

Sitzungsdaten

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.


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();

Latte

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.



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());
}

Awesome-plugins/tracy

Tracy

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.

Installation

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

Grundkonfiguration

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);
}

Hilfreiche Tipps

Wenn Sie Ihren Code debuggen, gibt es einige sehr hilfreiche Funktionen, um Daten für Sie auszugeben.

Awesome-plugins/active_record

Flug aktiver Datensatz

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.

Klicken Sie hier für das Repository auf GitHub.

Grundbeispiel

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!

Installation

Einfach mit Composer installieren

composer require flightphp/active-record 

Verwendung

Dies kann als eigenständige Bibliothek oder mit dem Flight PHP Framework verwendet werden. Ganz wie Sie möchten.

Eigenständig

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!

Als Methode in Flight registrieren

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);

Methoden von 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:

<?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');
    }
}

CRUD-Funktionen

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 (v0.4.0)

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();
Textbasierte Primärschlüssel

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.

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 (v0.4.0)

Dies ist ein Alias für die Methode dirty(). Es ist etwas klarer, was Sie tun.

$benutzer->copyFrom([ 'name' => 'etwas', 'password' => password_hash('ein anderes Passwort') ]);
$benutzer->update(); // sowohl Name als auch Passwort werden aktualisiert.

isDirty(): boolean (v0.4.0)

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 (v0.4.1)

Nach Ausführung einer find(), findAll(), insert(), update() oder save()-Methode können Sie den erstellten SQL abrufen und für Debug-Zwecke verwenden.

SQL-Abfragemethoden

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.

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();

WO-Bedingungen

equal(string $field, mixed $value) / eq(string $field, mixed $value)

Wo field = $value

$benutzer->eq('id', 1)->find();

notEqual(string $field, mixed $value) / ne(string $field, mixed $value)

Wo field <> $value

$benutzer->ne('id', 1)->find();

isNull(string $field)

Wo field IS NULL

$benutzer->isNull('id')->find();

isNotNull(string $field) / notNull(string $field)

Wo field IS NOT NULL

$benutzer->isNotNull('id')->find();

greaterThan(string $field, mixed $value) / gt(string $field, mixed $value)

Wo field > $value

$benutzer->gt('id', 1)->find();

lessThan(string $field, mixed $value) / lt(string $field, mixed $value)

Wo 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

$benutzer->ge('id', 1)->find();

lessThanOrEqual(string $field, mixed $value) /le(string $field, mixed $value) / lte(string $field, mixed $value)

Wo 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

$benutzer->like('name', 'de')->find();

in(string $field, array $values) / notIn(string $field, array $values)

Wo field IN($value) oder field NOT IN($value)

$benutzer->in('id', [1, 2])->find();

between(string $field, array $values)

Wo field BETWEEN $value AND $value1

$benutzer->between('id', [1, 2])->find();

Beziehungen

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.

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?

Festlegen von benutzerdefinierten Daten

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.

$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;

Ereignisse

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)

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 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!

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:';
    } 
}

Verwaltung der Datenbankverbindung

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).

$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.

Beiträge

Bitte tun Sie das. :D

Einrichtung

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).

Stellen Sie außerdem sicher, dass Sie composer beautify und composer phpcs ausführen, um Fehler in der Formatierung zu beheben.

Lizenz

MIT

Awesome-plugins/latte

Latte

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.

Installation

Installieren Sie mit Composer.

composer require latte/latte

Grundkonfiguration

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')));
});

Einfaches Layoutbeispiel

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">
            &copy; 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!

Awesome-plugins/awesome_plugins

Fantastische Plugins

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/Berechtigung

Authentifizierung und Berechtigung sind entscheidend für jede Anwendung, die Steuerungen erfordert, um festzulegen, wer auf was zugreifen kann.

Zwischenspeicher

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

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

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

Debuggen ist entscheidend, wenn Sie in Ihrer lokalen Umgebung entwickeln. Es gibt ein paar Plugins, die Ihr Debugging-Erlebnis verbessern können.

Datenbanken

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

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.

Sitzung

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.

Template

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.

Mitarbeit

Haben Sie ein Plugin, das Sie teilen möchten? Reichen Sie einen Pull-Request ein, um es der Liste hinzuzufügen!

Media

Medien

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.

Artikel

Videos

Examples

Brauchen Sie einen schnellen Einstieg?

Sie haben zwei Möglichkeiten, um mit Flight zu beginnen:

Brauchen Sie etwas Inspiration?

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!

Möchten Sie Ihr eigenes Beispiel teilen?

Wenn Sie ein Projekt haben, das Sie teilen möchten, reichen Sie bitte einen Pull-Request ein, um es zu dieser Liste hinzuzufügen!

Install/install

Installation

Dateien herunterladen

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:

composer require flightphp/core

ODER Sie können die Dateien hier herunterladen und direkt in Ihr Webverzeichnis extrahieren.

Konfigurieren Sie Ihren Webserver

Eingebauter PHP-Entwicklungsserver

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.

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:

php -S localhost:8000 -t public/

Öffnen Sie dann Ihren Browser und gehen Sie zu http://localhost:8000.

Apache

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.

Für Apache bearbeiten Sie Ihre .htaccess-Datei wie folgt:

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 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:

RewriteEngine On
RewriteRule ^(.*)$ index.php

Nginx

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:

server {
  location / {
    try_files $uri $uri/ /index.php;
  }
}

Erstellen Sie Ihre index.php-Datei

<?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();

PHP installieren

Wenn Sie bereits über php auf Ihrem System verfügen, überspringen Sie diese Anweisungen und wechseln Sie zum Download-Abschnitt

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.

macOS

PHP mit Homebrew installieren

  1. Homebrew installieren (wenn nicht bereits installiert):

    • Öffnen Sie das Terminal und führen Sie aus:
      /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  2. PHP installieren:

    • Installieren Sie die neueste Version:
      brew install php
    • Um eine bestimmte Version zu installieren, z. B. PHP 8.1:
      brew tap shivammathur/php
      brew install shivammathur/php/php@8.1
  3. Zwischen PHP-Versionen wechseln:

    • Verknüpfen Sie die aktuelle Version und verknüpfen Sie die gewünschte Version:
      brew unlink php
      brew link --overwrite --force php@8.1
    • Überprüfen Sie die installierte Version:
      php -v

Windows 10/11

PHP manuell installieren

  1. PHP herunterladen:

    • Besuchen Sie PHP für Windows und laden Sie die neueste oder eine bestimmte Version (z. B. 7.4, 8.0) als zip-Datei ohne Thread-Sicherheit herunter.
  2. PHP extrahieren:

    • Extrahieren Sie die heruntergeladene Zip-Datei nach C:\php.
  3. PHP zum System-PATH hinzufügen:

    • Gehen Sie zu Systemeigenschaften > Umgebungsvariablen.
    • Unter Systemvariablen suchen Sie Path und klicken Sie auf Bearbeiten.
    • Fügen Sie den Pfad C:\php (oder wo immer Sie PHP extrahiert haben) hinzu.
    • Klicken Sie auf OK, um alle Fenster zu schließen.
  4. PHP konfigurieren:

    • Kopieren Sie php.ini-development nach php.ini.
    • Bearbeiten Sie php.ini, um PHP nach Bedarf zu konfigurieren (z. B. extension_dir setzen, Erweiterungen aktivieren).
  5. PHP-Installation überprüfen:

    • Öffnen Sie die Eingabeaufforderung und führen Sie aus:
      php -v

Mehrere PHP-Versionen installieren

  1. Wiederholen Sie die obigen Schritte für jede Version und platzieren Sie sie jeweils in einem separaten Verzeichnis (z. B. C:\php7, C:\php8).

  2. Zwischen den Versionen wechseln, indem Sie die System-PATH-Variable anpassen, um auf das gewünschte Versionsverzeichnis zu verweisen.

Ubuntu (20.04, 22.04, usw.)

PHP mit apt installieren

  1. Paketlisten aktualisieren:

    • Öffnen Sie das Terminal und führen Sie aus:
      sudo apt update
  2. PHP installieren:

    • Installieren Sie die neueste PHP-Version:
      sudo apt install php
    • Um eine bestimmte Version zu installieren, z. B. PHP 8.1:
      sudo apt install php8.1
  3. Zusätzliche Module installieren (optional):

    • Zum Beispiel, um die MySQL-Unterstützung zu installieren:
      sudo apt install php8.1-mysql
  4. Zwischen PHP-Versionen wechseln:

    • Verwenden Sie update-alternatives:
      sudo update-alternatives --set php /usr/bin/php8.1
  5. Installierte Version überprüfen:

    • Führen Sie aus:
      php -v

Rocky Linux

PHP mit yum/dnf installieren

  1. EPEL-Repository aktivieren:

    • Öffnen Sie das Terminal und führen Sie aus:
      sudo dnf install epel-release
  2. Remi-Repository installieren:

    • Führen Sie aus:
      sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
      sudo dnf module reset php
  3. PHP installieren:

    • Um die Standardversion zu installieren:
      sudo dnf install php
    • Um eine bestimmte Version zu installieren, z. B. PHP 7.4:
      sudo dnf module install php:remi-7.4
  4. Zwischen PHP-Versionen wechseln:

    • Verwenden Sie den Befehl dnf module:
      sudo dnf module reset php
      sudo dnf module enable php:remi-8.0
      sudo dnf install php
  5. Überprüfen Sie die installierte Version:

    • Führen Sie aus:
      php -v

Allgemeine Hinweise