FR

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.

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

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

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

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

  5. Des standards plutôt que de l’invention

    Interfaces PSR, ICU MessageFormat, Problem Details et OpenTelemetry plutôt que des conventions maison.

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

  1. Écrire

    Des classes typées, des attributs et des contrats explicites décrivent l’application.

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

  3. Exécuter

    L’application compilée traite les requêtes comme un worker persistant, avec un scope neuf pour chaque requête.

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

app/HelloHandler.phpPHP
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

app/CreateTicket.phpPHP
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

views/products.weft.phpWeft
<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

app/Author.phpPHP
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

app/Jobs/SendInvoice.phpPHP
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

app/Workflows/fulfilment.phpPHP
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

orders.tsTypeScript
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.

  • plerino/tessera

    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.

  • plerino/aegis

    Authentification et autorisation

    Sessions, guards, passkeys, TOTP, jetons d’API et politiques à refus par défaut.

  • plerino/flux

    Traitements en arrière-plan

    Files d’attente, jobs, lots et workflows durables, avec livraison au moins une fois et gestion dead-letter.

  • plerino/comet

    Temps réel

    Un serveur, des canaux, la présence, le rejeu et les server-sent events, avec un client TypeScript typé.

  • plerino/lens

    Observabilité

    Traces, métriques et journaux OpenTelemetry en OTLP, ainsi que des panneaux de développement.

  • plerino/weft

    Templates compilés

    Weft compile des templates natifs HTML en PHP et échappe chaque interpolation.

  • plerino/mail

    E-mail et notifications

    Des messages signés DKIM sur plusieurs transports, et des notifications par e-mail, SMS, push et messagerie.

  • plerino/cli

    Ligne de commande

    Un seul binaire pour compiler, servir, inspecter les routes et les services, et vérifier l’environnement.

  • plerino/scheduler

    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.

  1. Backends d’API

    Des services HTTP typés au traitement strict des entrées

  2. SaaS et plateformes multiservices

    Comptes, localisation, montants et communication

  3. Applications temps réel

    Mises à jour en direct, présence et canaux reprenables

  4. Tâches en arrière-plan et workflows

    Files d’attente, nouvelles tentatives, planifications et processus durables

  5. Outils internes et back-offices

    Écrans rendus côté serveur, formulaires et approbations

  6. Intégrations événementielles

    Événements, outbox et appels sortants protégés

  7. Environnements réglementés ou sensibles

    Un comportement vérifiable pour l’authentification, les clés et les journaux

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

Fondations
HTTP et exécution
Templates et front-end
Données
Traitements en arrière-plan
Temps réel
Sécurité
Communication
Support applicatif
Observabilité

Parcourir tous les paquets

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

  1. 01Style de codePER-CS 3.0 et les règles du dépôt
  2. 02Analyse statiqueNiveau maximal, règles strictes et règles du projet
  3. 03TestsExécutés en parallèle, avec une couverture minimale par paquet
  4. 04Tests de mutationUn score de mutation minimal par paquet
  5. 05Fuzzing et benchmarksDes exécutions de contrôle à chaque modification
  6. 06DocumentationChaque classe publique a sa page et chaque page compile
  7. 07Journal des modificationsChaque paquet modifié a son entrée
  8. 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

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.

Suivez la route vers la 1.0

Explorez ce qui existe aujourd’hui, ou écrivez-nous si vous souhaitez échanger sur le projet.

Explorer l’écosystèmeNous contacter

Saisissez votre recherche. Utilisez les flèches pour naviguer et Entrée pour ouvrir.

Suggestions