En développement actif vers la version 1.0
Compilé au build. Exécuté en worker.
Plerino est un framework PHP open source. Le routage, le conteneur de services, la configuration, les listeners d’événements et les templates sont compilés en amont ; l’application s’exécute ensuite comme un worker persistant.
Explorer l’écosystème Voir le fonctionnement
- Langage
- PHP 8.5.12+
- Licence
- MIT
- Mainteneur
- PHRAMEA
- Version
- Avant la 1.0
01Principes
Six règles, appliquées à chaque paquet
Plerino existe pour rendre les backends PHP prévisibles. Les décisions habituellement prises pendant l’exécution d’une application sont prises une seule fois, au moment du build.
La compilation d’abord
Le build résout une fois les routes, les services, la configuration, les listeners et les templates. Rien n’est découvert par analyse à l’exécution.
Le worker d’abord
L’application démarre une fois et traite de nombreuses requêtes. Le recyclage des workers et les points de contrôle d’état sont intégrés.
Aucune magie
Des classes typées, des attributs et des contrats explicites. Des règles d’analyse statique propres au projet rejettent les constructions qui masquent le comportement.
Sécurisé par défaut
libsodium est le seul fournisseur de cryptographie, les secrets sont masqués dans les journaux et les templates échappent la sortie par défaut.
Des standards plutôt que de l’invention
Interfaces PSR, ICU MessageFormat, Problem Details et OpenTelemetry plutôt que des conventions maison.
Des points d’extension stables
Les contrats résident dans un seul paquet : des tiers peuvent étendre Plerino sans le modifier.
02Fonctionnement
De la source au worker
Une chaîne, quatre étapes. Les conflits et les erreurs apparaissent au build, pas en production.
Écrire
Des classes typées, des attributs et des contrats explicites décrivent l’application.
Compiler
Le build résout une fois le conteneur, les routes et la configuration, et échoue en cas de conflit, par exemple entre deux routes qui se chevauchent.
Exécuter
L’application compilée traite les requêtes comme un worker persistant, avec un scope neuf pour chaque requête.
Observer
Traces, métriques et journaux sont exportés en OTLP, avec échantillonnage et masquage.
03Visite du code
À quoi ressemble le code
Chaque exemple utilise l’API telle qu’elle existe aujourd’hui dans le dépôt. Les API peuvent encore évoluer avant la 1.0.
Les routes sont des attributs
Une route se déclare sur le handler et se compile en un matcher statique. Les paramètres typés sont convertis avant l’exécution du handler.
- Paramètres typés tels que {id:int}, ulid, uuid, slug et date
- Deux routes qui se chevauchent font échouer le build
- Tableaux et objets deviennent des réponses JSON
Paquets concernés
use Plerino\Routing\Attributes\Get;
#[Get('/hello/{name}', name: 'hello')]
final readonly class HelloHandler
{
public function __invoke(string $name): array
{
return ['message' => 'Hello, ' . $name];
}
}
Les requêtes deviennent des objets typés
Une classe d’entrée déclare l’origine de chaque valeur. Scalaires, enums, entrées imbriquées et tableaux sont convertis strictement.
- Sources : route, query, corps et en-tête
- Une résolution en échec liste les erreurs par champ
- Les règles de longueur ou de format relèvent du paquet de validation
Paquets concernés
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 = '',
) {}
}
Des templates natifs HTML
Les templates Weft sont compilés en PHP au build. Chaque interpolation est échappée et les composants reçoivent des props typées.
- Composants, slots et props typées
- Échappement par défaut dans chaque contexte
- Conçu pour une politique de sécurité du contenu stricte
Paquets concernés
<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>
Des entités décrites par attributs
Tessera valide les métadonnées des entités et les compile au build : un worker n’a jamais à recourir à la réflexion pour trouver une colonne.
- PostgreSQL, MySQL et SQLite
- Query builder immuable à valeurs liées
- Migrations générées à partir des différences de schéma
Paquets concernés
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 = '',
) {}
}
Les jobs sont des classes final readonly
Les paramètres du constructeur sont les données, __invoke est le handler. Les jobs circulent dans la file sous forme d’enveloppes JSON, jamais d’objets sérialisés.
- Nouvelles tentatives avec backoff et jitter
- Jobs uniques et clés d’idempotence
- Un stockage dead-letter pour les messages empoisonnés
Paquets concernés
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);
}
}
Des workflows durables
Un workflow est une liste ordonnée d’étapes, de minuteries et d’approbations. Chaque décision est ajoutée à un journal d’événements et l’état est reconstruit par rejeu.
- La compensation s’exécute dans l’ordre inverse
- Minuteries et approbation humaine
- Rien ne vit uniquement en mémoire
Paquets concernés
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());
Un client temps réel typé
Comet parle son protocole sur WebSocket et sur server-sent events. Le client TypeScript reprend les canaux après une déconnexion.
- Canaux à motifs typés, protégés par des politiques
- Présence et fenêtre de rejeu
- Canaux chiffrés de bout en bout
Paquets concernés
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();
04Fonctionnalités
Un ensemble cohérent de paquets
Chaque paquet a ses propres tests, sa documentation et son journal des modifications, et suit les mêmes règles.
-
Accès aux données
Entités, repositories, query builder et migrations pour les bases SQL, un magasin de documents pour MongoDB et la recherche vectorielle derrière un contrat unique.
-
Authentification et autorisation
Sessions, guards, passkeys, TOTP, jetons d’API et politiques à refus par défaut.
-
Traitements en arrière-plan
Files d’attente, jobs, lots et workflows durables, avec livraison au moins une fois et gestion dead-letter.
-
Temps réel
Un serveur, des canaux, la présence, le rejeu et les server-sent events, avec un client TypeScript typé.
-
Observabilité
Traces, métriques et journaux OpenTelemetry en OTLP, ainsi que des panneaux de développement.
-
Templates compilés
Weft compile des templates natifs HTML en PHP et échappe chaque interpolation.
-
E-mail et notifications
Des messages signés DKIM sur plusieurs transports, et des notifications par e-mail, SMS, push et messagerie.
-
Ligne de commande
Un seul binaire pour compiler, servir, inspecter les routes et les services, et vérifier l’environnement.
-
Planification
Les planifications sont des attributs compilés au build, avec fuseaux horaires, protection contre les chevauchements et verrous entre nœuds.
05Cas d’usage
Où Plerino trouve sa place
Plerino est un framework backend généraliste. Voici les types de systèmes pour lesquels ses paquets sont conçus.
Backends d’API
Des services HTTP typés au traitement strict des entrées
SaaS et plateformes multiservices
Comptes, localisation, montants et communication
Applications temps réel
Mises à jour en direct, présence et canaux reprenables
Tâches en arrière-plan et workflows
Files d’attente, nouvelles tentatives, planifications et processus durables
Outils internes et back-offices
Écrans rendus côté serveur, formulaires et approbations
Intégrations événementielles
Événements, outbox et appels sortants protégés
Environnements réglementés ou sensibles
Un comportement vérifiable pour l’authentification, les clés et les journaux
Tous les cas d’usage
Adossés à des paquets réels
06Écosystème
Les paquets par domaine
Un monorepo de paquets Composer. Chacun s’installe séparément.
Fondé sur des standards
- 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é
Qualité d’ingénierie
Aucune modification n’est fusionnée avant d’avoir franchi l’ensemble des contrôles de qualité sur PHP 8.5 et PHP 8.6.
Les affirmations de performance et de sécurité ne sont formulées que lorsqu’un benchmark ou un test reproductible les étaye. Aucun résultat de benchmark n’a encore été publié.
- 01Style de codePER-CS 3.0 et les règles du dépôt
- 02Analyse statiqueNiveau maximal, règles strictes et règles du projet
- 03TestsExécutés en parallèle, avec une couverture minimale par paquet
- 04Tests de mutationUn score de mutation minimal par paquet
- 05Fuzzing et benchmarksDes exécutions de contrôle à chaque modification
- 06DocumentationChaque classe publique a sa page et chaque page compile
- 07Journal des modificationsChaque paquet modifié a son entrée
- 08Dépendances et secretsAudit des dépendances et détection de secrets
08État
Où en est le projet
Plerino est en développement actif vers la version 1.0. Il n’existe pas encore de version stable et les API publiques peuvent évoluer avant la 1.0.
Implémenté dans le dépôt
- Fondations, conteneur, noyau et chaîne de build
- HTTP, routage et pilotes pour le worker FrankenPHP et PHP-FPM
- Templates Weft compilés
- Accès aux données SQL, magasin de documents et recherche vectorielle
- Files d’attente, jobs, workflows, planificateur et événements
- Serveur temps réel et client TypeScript
- Authentification et autorisation
- E-mail et notifications
- Télémétrie OpenTelemetry et panneaux de développement
Paquets prévus
- Pilotes Swoole et RoadRunner
- Protection applicative à l’exécution
- Outils de classification des données et d’audit
- Feature flags
- Pilotes de recherche
- Adaptateur front-end avec rendu côté serveur
Avant la 1.0
- Squelette d’application et kits de démarrage
- Documentation publique sur ce site
- Version stable 1.0
09FAQ
Questions fréquentes
Qu’est-ce que Plerino ?
Un framework PHP open source qui compile le routage, les services, la configuration, les listeners et les templates au build et exécute l’application comme un worker persistant.
Plerino est-il prêt pour la production ?
Pas encore. Il n’existe pas de version stable et les API publiques peuvent évoluer avant la 1.0.
Quelles versions de PHP sont prises en charge ?
PHP 8.5.12 ou ultérieur. Chaque modification est vérifiée sur PHP 8.5 et PHP 8.6.
Quels environnements d’exécution sont pris en charge ?
Le paquet d’exécution fournit des pilotes pour le mode worker de FrankenPHP et pour PHP-FPM. Des pilotes pour Swoole et RoadRunner sont prévus.
Quelles bases de données sont prises en charge ?
PostgreSQL, MySQL et SQLite via la couche SQL, MongoDB via le magasin de documents, et la recherche vectorielle avec pgvector, sqlite-vec et Atlas Vector Search.
Combien cela coûte-t-il et qui le maintient ?
Plerino est un logiciel libre sous licence MIT, maintenu par PHRAMEA.
Où se trouve le code source ?
Le dépôt de code source n’est pas encore accessible au public. Pour toute question sur le projet, écrivez à hello@plerino.dev.
Comment signaler un problème de sécurité ?
Envoyez un signalement privé à security@plerino.dev. Merci de ne pas ouvrir de ticket public. Une clé OpenPGP est disponible pour les signalements chiffrés.
Où lire la documentation ?
La documentation est en cours de préparation en vue de sa publication sur ce site.
10Contact
Contact
Écrivez à l’adresse qui correspond à votre sujet.
- Généralhello@plerino.devQuestions sur le projet
- Sécuritésecurity@plerino.devSignalements privés de vulnérabilités
- Pressepress@plerino.devPresse et partenariats
- Abusabuse@plerino.devSignalements d’usage abusif de ce site ou de ses adresses
Suivez la route vers la 1.0
Explorez ce qui existe aujourd’hui, ou écrivez-nous si vous souhaitez échanger sur le projet.