En desarrollo activo hacia la versión 1.0
Compilado en el build. En ejecución como worker.
Plerino es un framework PHP de código abierto. El enrutamiento, el contenedor de servicios, la configuración, los listeners de eventos y las plantillas se compilan por adelantado; después, la aplicación se ejecuta como un worker de larga duración.
Explorar el ecosistema Ver cómo funciona
- Lenguaje
- PHP 8.5.12+
- Licencia
- MIT
- Responsable
- PHRAMEA
- Versión
- Previa a la 1.0
01Principios
Seis reglas, aplicadas a cada paquete
Plerino existe para que los backends PHP sean predecibles. Las decisiones que suelen tomarse mientras la aplicación se ejecuta se toman una sola vez, al compilarla.
Primero, la compilación
El build resuelve una vez las rutas, los servicios, la configuración, los listeners y las plantillas. Nada se descubre escaneando en tiempo de ejecución.
Primero, el worker
La aplicación arranca una vez y atiende muchas peticiones. El reciclaje de workers y los endpoints de salud vienen integrados.
Sin magia
Clases tipadas, atributos y contratos explícitos. Reglas de análisis estático propias del proyecto rechazan las construcciones que ocultan el comportamiento.
Seguro por defecto
libsodium es el único proveedor de criptografía, los secretos se ocultan en los registros y las plantillas escapan la salida por defecto.
Estándares antes que inventos
Interfaces PSR, ICU MessageFormat, Problem Details y OpenTelemetry en lugar de convenciones propias.
Puntos de extensión estables
Los contratos viven en un único paquete, de modo que terceros pueden ampliar Plerino sin modificarlo.
02Cómo funciona
Del código fuente al worker
Un solo canal, cuatro etapas. Los conflictos y los errores afloran en el build, no en producción.
Escribir
Clases tipadas, atributos y contratos explícitos describen la aplicación.
Compilar
El build resuelve una vez el contenedor, las rutas y la configuración, y falla ante conflictos como rutas que se solapan.
Ejecutar
La aplicación compilada atiende las peticiones como un worker de larga duración, con un ámbito nuevo para cada petición.
Observar
Las trazas, las métricas y los registros se exportan por OTLP, con muestreo y ocultación de datos sensibles.
03Recorrido por el código
Qué aspecto tiene el código
Cada ejemplo usa la API tal como existe hoy en el repositorio. Las API aún pueden cambiar antes de la 1.0.
Las rutas son atributos
Una ruta se declara sobre el handler y se compila en un matcher estático. Los parámetros tipados se convierten antes de que se ejecute el handler.
- Parámetros tipados como {id:int}, ulid, uuid, slug y date
- Las rutas que se solapan hacen fallar el build
- Los arrays y los objetos se convierten en respuestas JSON
Paquetes implicados
use Plerino\Routing\Attributes\Get;
#[Get('/hello/{name}', name: 'hello')]
final readonly class HelloHandler
{
public function __invoke(string $name): array
{
return ['message' => 'Hello, ' . $name];
}
}
Las peticiones se convierten en objetos tipados
Una clase de entrada declara de dónde procede cada valor. Los escalares, los enums, las entradas anidadas y los arrays se convierten de forma estricta.
- Orígenes: ruta, query, cuerpo y cabecera
- Una resolución fallida enumera los errores por campo
- Las reglas de longitud o formato pertenecen al paquete de validación
Paquetes implicados
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 = '',
) {}
}
Plantillas nativas de HTML
Las plantillas Weft se compilan a PHP en el build. Cada interpolación se escapa y los componentes reciben props tipadas.
- Componentes, slots y props tipadas
- Escapado por defecto en cada contexto
- Pensado para una política de seguridad de contenido estricta
Paquetes implicados
<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>
Entidades descritas con atributos
Tessera valida los metadatos de las entidades y los compila en el build, de modo que un worker nunca recurre a la reflexión para encontrar una columna.
- PostgreSQL, MySQL y SQLite
- Query builder inmutable con valores enlazados
- Migraciones generadas a partir de las diferencias de esquema
Paquetes implicados
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 = '',
) {}
}
Los trabajos son clases final readonly
Los parámetros del constructor son los datos y __invoke es el handler. Los trabajos viajan por la cola como sobres JSON, nunca como objetos serializados.
- Reintentos con backoff y jitter
- Trabajos únicos y claves de idempotencia
- Un almacén dead-letter para los mensajes envenenados
Paquetes implicados
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);
}
}
Flujos de trabajo duraderos
Un flujo de trabajo es una lista ordenada de pasos, temporizadores y aprobaciones. Cada decisión se añade a un registro de eventos y el estado se reconstruye por reproducción.
- La compensación se ejecuta en orden inverso
- Temporizadores y aprobación humana
- Nada vive únicamente en memoria
Paquetes implicados
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 cliente tipado de tiempo real
Comet habla su protocolo sobre WebSocket y server-sent events. El cliente TypeScript reanuda los canales tras una desconexión.
- Canales con patrones tipados y políticas
- Presencia y ventana de reproducción
- Canales cifrados de extremo a extremo
Paquetes implicados
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();
04Capacidades
Un conjunto coherente de paquetes
Cada paquete tiene sus propias pruebas, su documentación y su registro de cambios, y sigue las mismas reglas.
-
Acceso a datos
Entidades, repositorios, query builder y migraciones para bases de datos SQL, un almacén de documentos para MongoDB y búsqueda vectorial tras un único contrato.
-
Autenticación y autorización
Sesiones, guards, passkeys, TOTP, tokens de API y políticas de denegación por defecto.
-
Trabajo en segundo plano
Colas, trabajos, lotes y flujos de trabajo duraderos, con entrega al menos una vez y gestión dead-letter.
-
Tiempo real
Servidor, canales, presencia, reproducción y server-sent events, con un cliente TypeScript tipado.
-
Observabilidad
Trazas, métricas y registros de OpenTelemetry por OTLP, además de paneles de desarrollo.
-
Plantillas compiladas
Weft compila plantillas nativas de HTML a PHP y escapa cada interpolación.
-
Correo y notificaciones
Mensajes firmados con DKIM a través de varios transportes y notificaciones por correo, SMS, push y mensajería.
-
Línea de comandos
Un único binario para compilar, servir, inspeccionar rutas y servicios y comprobar el entorno.
-
Planificación
Las planificaciones son atributos compilados en el build, con zonas horarias, protección contra solapamientos y bloqueos entre nodos.
05Casos de uso
Dónde encaja Plerino
Plerino es un framework de backend de propósito general. Estos son los tipos de sistemas para los que están pensados sus paquetes.
Backends de API
Servicios HTTP tipados con tratamiento estricto de la entrada
SaaS y plataformas multiservicio
Cuentas, localización, importes y comunicación
Aplicaciones en tiempo real
Actualizaciones en vivo, presencia y canales reanudables
Trabajos en segundo plano y flujos de trabajo
Colas, reintentos, planificaciones y procesos duraderos
Herramientas internas y back offices
Pantallas renderizadas en el servidor, formularios y aprobaciones
Integraciones orientadas a eventos
Eventos, outbox y llamadas salientes protegidas
Entornos regulados o sensibles a la seguridad
Comportamiento verificable en autenticación, claves y registros
Todos los casos de uso
Respaldados por paquetes reales
06Ecosistema
Paquetes por área
Un monorepo de paquetes de Composer. Cada uno se instala por separado.
Construido sobre estándares
- 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
07Calidad
Calidad de ingeniería
Ningún cambio se integra hasta superar todos los controles de calidad en PHP 8.5 y PHP 8.6.
Las afirmaciones sobre rendimiento y seguridad solo se hacen cuando las respalda un benchmark o una prueba reproducible. Aún no se ha publicado ningún resultado de benchmark.
- 01Estilo de códigoPER-CS 3.0 con las reglas del repositorio
- 02Análisis estáticoNivel máximo, reglas estrictas y reglas del proyecto
- 03PruebasEn paralelo, con una cobertura mínima por paquete
- 04Pruebas de mutaciónUna puntuación de mutación mínima por paquete
- 05Fuzzing y benchmarksEjecuciones de humo en cada cambio
- 06DocumentaciónCada clase pública tiene su página y cada página compila
- 07Registro de cambiosCada paquete modificado tiene su entrada
- 08Dependencias y secretosAuditoría de dependencias y detección de secretos
08Estado
En qué punto está el proyecto
Plerino está en desarrollo activo hacia la versión 1.0. Aún no hay una versión estable y las API públicas pueden cambiar antes de la 1.0.
Implementado en el repositorio
- Fundamentos, contenedor, núcleo y canal de compilación
- HTTP, enrutamiento y drivers para el worker de FrankenPHP y PHP-FPM
- Plantillas Weft compiladas
- Acceso a datos SQL, almacén de documentos y búsqueda vectorial
- Colas, trabajos, flujos de trabajo, planificador y eventos
- Servidor de tiempo real y cliente TypeScript
- Autenticación y autorización
- Correo y notificaciones
- Telemetría OpenTelemetry y paneles de desarrollo
Paquetes previstos
- Drivers para Swoole y RoadRunner
- Protección de la aplicación en tiempo de ejecución
- Herramientas de clasificación de datos y auditoría
- Feature flags
- Drivers de búsqueda
- Adaptador de front-end con renderizado en el servidor
Antes de la 1.0
- Esqueleto de aplicación y kits de inicio
- Documentación pública en este sitio
- Versión estable 1.0
09FAQ
Preguntas frecuentes
¿Qué es Plerino?
Un framework PHP de código abierto que compila el enrutamiento, los servicios, la configuración, los listeners y las plantillas en el build y ejecuta la aplicación como un worker de larga duración.
¿Está Plerino listo para producción?
Todavía no. No hay una versión estable y las API públicas pueden cambiar antes de la 1.0.
¿Qué versiones de PHP admite?
PHP 8.5.12 o posterior. Cada cambio se comprueba en PHP 8.5 y PHP 8.6.
¿Qué entornos de ejecución admite?
El paquete de ejecución incluye drivers para el modo worker de FrankenPHP y para PHP-FPM. Los drivers para Swoole y RoadRunner están previstos.
¿Qué bases de datos admite?
PostgreSQL, MySQL y SQLite mediante la capa SQL, MongoDB mediante el almacén de documentos y búsqueda vectorial con pgvector, sqlite-vec y Atlas Vector Search.
¿Cuánto cuesta y quién lo mantiene?
Plerino es software libre bajo la licencia MIT, mantenido por PHRAMEA.
¿Dónde está el código fuente?
El repositorio de código fuente todavía no es de acceso público. Si tienes preguntas sobre el proyecto, escribe a hello@plerino.dev.
¿Cómo notifico un problema de seguridad?
Envía un informe privado a security@plerino.dev. Por favor, no abras una incidencia pública. Hay una clave OpenPGP disponible para los informes cifrados.
¿Dónde puedo leer la documentación?
La documentación se está preparando para su publicación en este sitio.
10Contacto
Contacto
Escribe a la dirección que corresponda a tu tema.
- Generalhello@plerino.devPreguntas sobre el proyecto
- Seguridadsecurity@plerino.devInformes privados de vulnerabilidades
- Prensapress@plerino.devPrensa y colaboraciones
- Abusoabuse@plerino.devAvisos sobre el uso indebido de este sitio o de sus direcciones
Sigue el camino hacia la 1.0
Explora lo que existe hoy o escríbenos si quieres hablar sobre el proyecto.