In aktiver Entwicklung auf dem Weg zu 1.0
Zur Build‑Zeit kompiliert. Als Worker in Betrieb.
Plerino ist ein Open-Source-PHP-Framework. Routing, Service-Container, Konfiguration, Event-Listener und Templates werden im Voraus kompiliert; anschließend läuft die Anwendung als langlebiger Worker.
Ökosystem entdecken So funktioniert es
- Sprache
- PHP 8.5.12+
- Lizenz
- MIT
- Träger
- PHRAMEA
- Release
- Vor 1.0
01Prinzipien
Sechs Regeln, die für jedes Paket gelten
Plerino soll PHP-Backends vorhersagbar machen. Entscheidungen, die üblicherweise zur Laufzeit einer Anwendung fallen, werden einmal getroffen: beim Build.
Build-Zeit zuerst
Der Build löst Routen, Services, Konfiguration, Listener und Templates einmal auf. Zur Laufzeit wird nichts durch Scannen ermittelt.
Worker zuerst
Die Anwendung startet einmal und bedient viele Anfragen. Worker-Recycling und Health-Endpunkte sind eingebaut.
Keine Magie
Typisierte Klassen, Attribute und explizite Verträge. Projekteigene Regeln der statischen Analyse lehnen Konstrukte ab, die Verhalten verbergen.
Standardmäßig sicher
libsodium ist der einzige Kryptografie-Anbieter, Secrets werden in Logs geschwärzt, und Templates maskieren Ausgaben standardmäßig.
Standards statt Eigenbau
PSR-Schnittstellen, ICU MessageFormat, Problem Details und OpenTelemetry statt proprietärer Konventionen.
Stabile Erweiterungspunkte
Die Verträge liegen in einem Paket, sodass Dritte Plerino erweitern können, ohne es zu verändern.
02Funktionsweise
Vom Quellcode zum Worker
Eine Pipeline, vier Stufen. Konflikte und Fehler zeigen sich im Build, nicht in der Produktion.
Schreiben
Typisierte Klassen, Attribute und explizite Verträge beschreiben die Anwendung.
Kompilieren
Der Build löst Container, Routen und Konfiguration einmal auf und schlägt bei Konflikten wie überlappenden Routen fehl.
Ausführen
Die kompilierte Anwendung bedient Anfragen als langlebiger Worker, mit einem frischen Scope für jede Anfrage.
Beobachten
Traces, Metriken und Logs werden per OTLP exportiert, mit Sampling und Schwärzung.
03Code-Tour
So sieht der Code aus
Jedes Beispiel verwendet die API so, wie sie heute im Repository vorliegt. APIs können sich vor 1.0 noch ändern.
Routen sind Attribute
Eine Route wird am Handler deklariert und in einen statischen Matcher kompiliert. Typisierte Parameter werden umgewandelt, bevor der Handler läuft.
- Typisierte Parameter wie {id:int}, ulid, uuid, slug und date
- Überlappende Routen lassen den Build fehlschlagen
- Arrays und Objekte werden zu JSON-Antworten
Beteiligte Pakete
use Plerino\Routing\Attributes\Get;
#[Get('/hello/{name}', name: 'hello')]
final readonly class HelloHandler
{
public function __invoke(string $name): array
{
return ['message' => 'Hello, ' . $name];
}
}
Anfragen werden zu typisierten Objekten
Eine Input-Klasse deklariert, woher jeder Wert stammt. Skalare, Enums, verschachtelte Inputs und Arrays werden strikt umgewandelt.
- Quellen: Route, Query, Body und Header
- Eine fehlgeschlagene Auflösung listet Fehler pro Feld
- Regeln wie Länge oder Format gehören ins Validierungspaket
Beteiligte Pakete
use Plerino\Http\ArrayOf;
use Plerino\Http\From;
use Plerino\Http\Input;
use Plerino\Http\Source;
final readonly class CreateTicket extends Input
{
public function __construct(
#[From(Source::Route)]
public int $project,
#[From(Source::Body)]
public string $title,
#[ArrayOf('int')]
public array $labels = [],
#[From(Source::Query)]
public bool $notify = false,
#[From(Source::Header, 'X-Request-Id')]
public string $requestId = '',
) {}
}
HTML-native Templates
Weft-Templates werden zur Build-Zeit zu PHP kompiliert. Jede Interpolation wird maskiert, und Komponenten erhalten typisierte Props.
- Komponenten, Slots und typisierte Props
- Standardmäßiges Escaping in jedem Kontext
- Ausgelegt auf eine strikte Content Security Policy
Beteiligte Pakete
<l-props>string $heading, array $products</l-props>
<Layout :title="$heading">
<h1>{{ $heading }}</h1>
<ul l-if="$products !== []">
<li l-each="$products as $name => $price">{{ $name }}: {{ $price }}</li>
</ul>
<p l-else>No products.</p>
</Layout>
Per Attribut beschriebene Entitäten
Tessera validiert die Metadaten der Entitäten und kompiliert sie zur Build-Zeit; ein Worker muss nie per Reflection nach einer Spalte suchen.
- PostgreSQL, MySQL und SQLite
- Unveränderlicher Query Builder mit gebundenen Werten
- Aus Schema-Unterschieden generierte Migrationen
Beteiligte Pakete
use Plerino\Tessera\Attributes\Column;
use Plerino\Tessera\Attributes\ColumnType;
use Plerino\Tessera\Attributes\Entity;
use Plerino\Tessera\Attributes\HasMany;
use Plerino\Tessera\Attributes\Id;
use Plerino\Tessera\Attributes\IdStrategy;
use Plerino\Tessera\Attributes\Unique;
#[Entity('authors')]
#[Unique(['name'])]
final class Author
{
#[HasMany(Post::class)]
public array $posts = [];
public function __construct(
#[Column(ColumnType::String)]
public string $name = '',
#[Id(IdStrategy::Ulid)]
public string $id = '',
) {}
}
Jobs sind final-readonly-Klassen
Die Konstruktorparameter sind die Daten, __invoke ist der Handler. Jobs durchlaufen die Queue als JSON-Envelopes, nie als serialisierte Objekte.
- Wiederholungen mit Backoff und Jitter
- Eindeutige Jobs und Idempotenzschlüssel
- Ein Dead-Letter-Speicher für Poison Messages
Beteiligte Pakete
use Plerino\Flux\Attributes\Job;
use Plerino\Flux\Attributes\Retry;
use Plerino\Flux\Attributes\Unique;
use Plerino\Flux\Job\Backoff;
use Plerino\Flux\Job\BackoffKind;
#[Job(queue: 'mail', timeout: 30)]
#[Retry(times: 4, backoff: new Backoff(BackoffKind::Exponential, seconds: 5, maxSeconds: 300, jitter: true))]
#[Unique(by: ['invoiceId'], for: 600)]
final readonly class SendInvoice
{
public function __construct(public int $invoiceId, public string $locale = 'en') {}
public function __invoke(InvoiceMailer $mailer): void
{
$mailer->send($this->invoiceId, $this->locale);
}
}
Dauerhafte Workflows
Ein Workflow ist eine geordnete Liste aus Schritten, Timern und Freigaben. Jede Entscheidung wird an ein Event-Log angehängt, und der Zustand entsteht durch Replay.
- Kompensation läuft in umgekehrter Reihenfolge
- Timer und Freigabe durch Menschen
- Nichts existiert nur im Arbeitsspeicher
Beteiligte Pakete
use Plerino\Clock\Duration;
use Plerino\Flux\Workflow\WorkflowDefinition;
$definition = WorkflowDefinition::named('order-fulfilment')
->step('reserve-stock', new ReserveStock())
->approval('manager-review', approvers: 2)
->timer('cooling-off', Duration::hours(24))
->step('charge-card', new ChargeCard());
Ein typisierter Echtzeit-Client
Comet spricht sein Protokoll über WebSocket und Server-Sent Events. Der TypeScript-Client setzt Channels nach einem Verbindungsabbruch fort.
- Channels mit typisierten Mustern und Policies
- Presence und ein Replay-Fenster
- Ende-zu-Ende-verschlüsselte Channels
Beteiligte Pakete
import { createClient } from '@plerino/comet';
const client = createClient({ url: 'wss://example.test/comet' });
const orders = client.channel('orders.42');
const stop = orders.on('paid', (payload, meta) => {
console.log(meta.id, payload);
});
await orders.publish('note', { text: 'shipped' });
stop();
orders.leave();
04Funktionsumfang
Ein konsistenter Satz von Paketen
Jedes Paket hat eigene Tests, eine eigene Dokumentation und ein Changelog und folgt denselben Regeln.
-
Datenzugriff
Entitäten, Repositories, Query Builder und Migrationen für SQL-Datenbanken, ein Dokumentenspeicher für MongoDB und Vektorsuche hinter einem einzigen Vertrag.
-
Authentifizierung und Autorisierung
Sessions, Guards, Passkeys, TOTP, API-Tokens und Policies nach dem Prinzip Deny by default.
-
Hintergrundverarbeitung
Queues, Jobs, Batches und dauerhafte Workflows mit At-least-once-Zustellung und Dead-Letter-Behandlung.
-
Echtzeit
Server, Channels, Presence, Replay und Server-Sent Events, mit einem typisierten TypeScript-Client.
-
Observability
OpenTelemetry-Traces, -Metriken und -Logs per OTLP sowie Entwicklungs-Panels.
-
Kompilierte Templates
Weft kompiliert HTML-native Templates zu PHP und maskiert jede Interpolation.
-
E-Mail und Benachrichtigungen
Nachrichten mit DKIM über mehrere Transporte sowie Benachrichtigungen per E-Mail, SMS, Push und Chat.
-
Kommandozeile
Ein Binary zum Bauen, Ausliefern, Prüfen von Routen und Services und zum Kontrollieren der Umgebung.
-
Zeitplanung
Zeitpläne sind Attribute, die zur Build-Zeit kompiliert werden, mit Zeitzonen, Überlappungsschutz und knotenübergreifenden Locks.
05Anwendungsfälle
Wo Plerino passt
Plerino ist ein universelles Backend-Framework. Für diese Arten von Systemen sind seine Pakete gebaut.
API-Backends
Typisierte HTTP-Dienste mit strikter Eingabeverarbeitung
SaaS- und Multi-Service-Plattformen
Konten, Lokalisierung, Geldbeträge und Kommunikation
Echtzeitanwendungen
Live-Updates, Presence und fortsetzbare Channels
Hintergrundjobs und Workflows
Queues, Wiederholungen, Zeitpläne und dauerhafte Prozesse
Interne Werkzeuge und Backoffice
Servergerenderte Oberflächen, Formulare und Freigaben
Ereignisgesteuerte Integrationen
Events, eine Outbox und abgesicherte ausgehende Aufrufe
Regulierte und sicherheitskritische Umgebungen
Nachprüfbares Verhalten bei Authentifizierung, Schlüsseln und Logs
Alle Anwendungsfälle
Auf reale Pakete abgebildet
06Ökosystem
Pakete nach Bereich
Ein Monorepo aus Composer-Paketen. Jedes lässt sich einzeln installieren.
Auf Standards gebaut
- PSR-3
- PSR-6
- PSR-7
- PSR-15
- PSR-16
- PSR-17
- PSR-18
- PSR-20
- ICU MessageFormat
- RFC 9457 Problem Details
- OpenTelemetry
- WebAuthn
- libsodium
07Qualität
Engineering-Qualität
Jede Änderung wird erst gemergt, wenn das vollständige Quality Gate unter PHP 8.5 und PHP 8.6 bestanden ist.
Aussagen zu Leistung und Sicherheit werden nur getroffen, wenn ein reproduzierbarer Benchmark oder Test sie belegt. Bisher wurden keine Benchmark-Ergebnisse veröffentlicht.
- 01Code-StilPER-CS 3.0 mit den Regeln des Repositorys
- 02Statische AnalyseHöchste Stufe, strikte Regeln und Projektregeln
- 03TestsParallel ausgeführt, mit Mindestabdeckung pro Paket
- 04MutationstestsEin Mindest-Mutation-Score pro Paket
- 05Fuzzing und BenchmarksSmoke-Läufe bei jeder Änderung
- 06DokumentationJede öffentliche Klasse hat eine Seite, und jede Seite kompiliert
- 07ChangelogJedes geänderte Paket hat einen Eintrag
- 08Abhängigkeiten und SecretsDependency-Audit und Secret-Scanning
08Stand
Wo das Projekt steht
Plerino wird aktiv in Richtung 1.0 entwickelt. Es gibt noch keine stabile Version, und öffentliche APIs können sich vor 1.0 ändern.
Im Repository umgesetzt
- Grundlagen, Container, Kernel und Build-Pipeline
- HTTP, Routing sowie die Treiber für FrankenPHP-Worker und PHP-FPM
- Kompilierte Weft-Templates
- SQL-Datenzugriff, Dokumentenspeicher und Vektorsuche
- Queues, Jobs, Workflows, Scheduler und Events
- Echtzeit-Server und TypeScript-Client
- Authentifizierung und Autorisierung
- E-Mail und Benachrichtigungen
- OpenTelemetry-Telemetrie und Entwicklungs-Panels
Geplante Pakete
- Treiber für Swoole und RoadRunner
- Schutz der Anwendung zur Laufzeit
- Werkzeuge für Datenklassifizierung und Audit
- Feature-Flags
- Suchtreiber
- Frontend-Adapter mit serverseitigem Rendering
Vor 1.0
- Anwendungsgerüst und Starter-Kits
- Öffentliche Dokumentation auf dieser Website
- Stabile Version 1.0
09FAQ
Häufige Fragen
Was ist Plerino?
Ein Open-Source-PHP-Framework, das Routing, Services, Konfiguration, Listener und Templates zur Build-Zeit kompiliert und die Anwendung als langlebigen Worker ausführt.
Ist Plerino produktionsreif?
Noch nicht. Es gibt keine stabile Version, und öffentliche APIs können sich vor 1.0 ändern.
Welche PHP-Versionen werden unterstützt?
PHP 8.5.12 oder neuer. Jede Änderung wird unter PHP 8.5 und PHP 8.6 geprüft.
Welche Laufzeitumgebungen werden unterstützt?
Das Laufzeitpaket enthält Treiber für den FrankenPHP-Worker-Modus und PHP-FPM. Treiber für Swoole und RoadRunner sind geplant.
Welche Datenbanken werden unterstützt?
PostgreSQL, MySQL und SQLite über die SQL-Schicht, MongoDB über den Dokumentenspeicher sowie Vektorsuche mit pgvector, sqlite-vec und Atlas Vector Search.
Was kostet es und wer betreut es?
Plerino ist freie Software unter der MIT-Lizenz und wird von PHRAMEA betreut.
Wo liegt der Quellcode?
Das Quellcode-Repository ist noch nicht öffentlich zugänglich. Bei Fragen zum Projekt schreiben Sie an hello@plerino.dev.
Wie melde ich ein Sicherheitsproblem?
Senden Sie eine vertrauliche Meldung an security@plerino.dev. Bitte eröffnen Sie kein öffentliches Issue. Für verschlüsselte Meldungen steht ein OpenPGP-Schlüssel bereit.
Wo finde ich die Dokumentation?
Die Dokumentation wird für die Veröffentlichung auf dieser Website vorbereitet.
10Kontakt
Kontakt
Schreiben Sie an die Adresse, die zu Ihrem Anliegen passt.
- Allgemeinhello@plerino.devFragen zum Projekt
- Sicherheitsecurity@plerino.devVertrauliche Meldungen von Schwachstellen
- Pressepress@plerino.devPresse und Kooperationen
- Missbrauchabuse@plerino.devMeldungen über den Missbrauch dieser Website oder ihrer Adressen
Begleiten Sie den Weg zu 1.0
Entdecken Sie, was heute vorhanden ist, oder schreiben Sie uns, wenn Sie über das Projekt sprechen möchten.