En resumen: los PSR (PHP Standards Recommendations) son estándares de PHP-FIG, un grupo de proyectos PHP consolidados. Establecen reglas e interfaces comunes, como PSR-4 para el autoloading, PSR-3 para los loggers, PSR-7 para los mensajes HTTP y PSR-11 para los contenedores. Cada PSR tiene un estado: aceptado, borrador, obsoleto o abandonado. Los PSR hacen el código más intercambiable y fácil de revisar, pero no cierran vulnerabilidades del intérprete de PHP como PHP2Shell.
Qué es PHP-FIG y qué son los PSR
PHP-FIG significa PHP Framework Interop Group. El propio grupo describe su objetivo como hacer avanzar PHP mediante la colaboración y los estándares. Detrás de un PSR no hay, por tanto, un fabricante, sino un acuerdo entre proyectos que quieren mantener su software compatible entre sí.
Para quienes toman decisiones, el beneficio es tangible: si una aplicación respeta las interfaces PSR, se puede cambiar, por ejemplo, la biblioteca de registro sin tocar todo el código. Eso reduce la dependencia de paquetes y proveedores concretos.
El camino de un PSR: de Pre-Draft a Accepted
Los estatutos de PHP-FIG describen un procedimiento fijo:
- Pre-Draft: se aclara si hay interés suficiente. Se forma un grupo de trabajo y, tras una votación favorable, la propuesta recibe un número de PSR.
- Draft: se elabora la propuesta; las alternativas y sus justificaciones pasan a un metadocumento.
- Review: la comunidad prueba la especificación con implementaciones de prueba, durante al menos cuatro semanas y hasta que existan dos implementaciones independientes y viables.
- Accepted: tras una votación favorable, el PSR queda aprobado; el grupo de trabajo se disuelve.
Existen además otros dos estados. Deprecated significa: aprobado, pero ya no recomendado, normalmente porque lo sustituye un estándar más reciente. Abandoned significa: ya no se trabaja en él.
Todos los PSR con su estado
Estado según la vista general de PHP-FIG en el momento de esta página:
| N.º | Título | Estado |
|---|---|---|
| PSR-0 | Autoloading Standard | obsoleto |
| PSR-1 | Basic Coding Standard | aceptado |
| PSR-2 | Coding Style Guide | obsoleto |
| PSR-3 | Logger Interface | aceptado |
| PSR-4 | Autoloading Standard | aceptado |
| PSR-5 | PHPDoc Standard | borrador |
| PSR-6 | Caching Interface | aceptado |
| PSR-7 | HTTP Message Interface | aceptado |
| PSR-8 | Huggable Interface | abandonado |
| PSR-9 | Security Advisories | abandonado |
| PSR-10 | Security Reporting Process | abandonado |
| PSR-11 | Container Interface | aceptado |
| PSR-12 | Extended Coding Style Guide | aceptado |
| PSR-13 | Hypermedia Links | aceptado |
| PSR-14 | Event Dispatcher | aceptado |
| PSR-15 | HTTP Handlers | aceptado |
| PSR-16 | Simple Cache | aceptado |
| PSR-17 | HTTP Factories | aceptado |
| PSR-18 | HTTP Client | aceptado |
| PSR-19 | PHPDoc tags | borrador |
| PSR-20 | Clock | aceptado |
| PSR-21 | Internationalization | borrador |
| PSR-22 | Application Tracing | borrador |
Los PSR más importantes en la práctica
- PSR-4 (autoloading): asocia nombres de clase con rutas de archivo y es la base del autoloader de Composer. Detalles en la página Namespaces y autoloading.
- PSR-1 y PER Coding Style: reglas comunes de escritura y formato. Según PHP-FIG, PER Coding Style amplía y sustituye a PSR-12 y presupone PSR-1.
- PSR-3 (logger): interfaz de logger unificada en el namespace
Psr\Log, con ocho niveles, deemergencyadebug. - PSR-7, PSR-15, PSR-17, PSR-18 (HTTP): interfaces para peticiones y respuestas, middleware, factorías y clientes HTTP. Muchos frameworks PHP se basan en ellas u ofrecen puentes.
- PSR-11 (contenedor): interfaz común para los contenedores de inyección de dependencias.
- PSR-6 y PSR-16 (caché): dos interfaces para cachés, una detallada y otra sencilla.
- PSR-14 y PSR-20 (eventos, reloj): interfaces comunes para eventos y para la hora actual. Un reloj intercambiable hace que el código que depende del tiempo, como la caducidad de tokens, sea fácil de probar.
Por cierto, los números no dicen nada sobre la importancia. Se asignan al entrar en la fase de borrador, por eso las propuestas obsoletas y abandonadas aparecen entre estándares importantes y aceptados.
<?php
use Psr\Log\LoggerInterface;
final class Bestellimport
{
public function __construct(private LoggerInterface $log) {}
public function importieren(string $datei): void
{
try {
// ... procesar el archivo ...
} catch (\Throwable $e) {
$this->log->error('Import von {datei} fehlgeschlagen', [
'datei' => basename($datei),
'exception' => $e,
]);
}
}
}
Qué tienen que ver los PSR con la seguridad
Varios estándares afectan directamente a la seguridad. PSR-3 establece que las excepciones se pasan en el contexto bajo la clave exception y que los marcadores como {datei} se sustituyen con valores del contexto. Los valores no deben escaparse de antemano, porque el logger no sabe dónde se mostrarán después. Quien muestra los logs en una interfaz web debe escaparlos allí. Más información en el artículo Registrar logs con seguridad.
PSR-7 describe los mensajes HTTP como objetos inmutables y ofrece, con UploadedFileInterface::moveTo(), una vía unificada para guardar los archivos subidos. La especificación exige que, después, el archivo original ya no exista. La comprobación del tipo de archivo y del destino sigue siendo tarea de la aplicación.
Llama la atención que PSR-9 (Security Advisories) y PSR-10 (Security Reporting Process) se hayan abandonado. No existe, por tanto, un estándar común para los avisos de seguridad; cada proyecto lo regula por sí mismo. Cómo trata el propio proyecto PHP las vulnerabilidades lo describe la página Cómo trata el proyecto PHP las vulnerabilidades de seguridad.
Frente a PHP2Shell, los estándares no ayudan: las vulnerabilidades CVE-2026-109618 y CVE-2026-109619 están en el intérprete. Es obligatoria la actualización a PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35 y el reinicio de todos los procesos de PHP.
¿Cómo ayuda PHP SOS en concreto?
- Revisamos cómo registra logs su aplicación y comprobamos que las excepciones acaben en el log, pero no las credenciales ni los identificadores de sesión.
- Valoramos cómo se han implementado el procesamiento de subidas y de HTTP, también cuando pasa por bibliotecas PSR-7.
- Examinamos los desarrollos propios en el marco de una auditoría de seguridad y prueba de penetración.
- Aplicamos las actualizaciones de PHP, reiniciamos todos los workers y documentamos el estado.
Preguntas frecuentes
¿Qué significa PSR?
PSR significa PHP Standards Recommendation. Las recomendaciones las elabora y consensúa PHP-FIG, el PHP Framework Interop Group. Son voluntarias, pero muchos frameworks y bibliotecas las aplican.
¿Sigue vigente PSR-12?
PSR-12 sigue figurando en PHP-FIG como aceptado. Sin embargo, PHP-FIG ha publicado con PER Coding Style un sucesor que, según su propia indicación, amplía y sustituye a PSR-12. La versión actual allí es la 3.1.
¿Existe un PSR para los avisos de seguridad?
Hubo dos propuestas: PSR-9 para Security Advisories y PSR-10 para el proceso de notificación de vulnerabilidades. Ambas figuran en PHP-FIG como abandonadas. Por eso, cada proyecto regula por su cuenta su proceso de notificación.
¿Debe mi proyecto cumplir los PSR?
No, no hay ninguna obligación. Pero PSR-4 para el autoloading y las interfaces como PSR-3 o PSR-7 facilitan mucho el uso de paquetes ajenos y el cambio de proveedores.