Накратко: PSR (PHP Standards Recommendations) са стандарти на PHP-FIG, група от утвърдени PHP проекти. Те определят общи правила и интерфейси, например PSR-4 за autoloading, PSR-3 за логъри, PSR-7 за HTTP съобщения и PSR-11 за контейнери. Всеки PSR има статус: приет, чернова, остарял или изоставен. PSR правят кода по-лесно заменяем и по-лесно проверяем, но не затварят уязвимости в интерпретатора на PHP като PHP2Shell.
Какво са PHP-FIG и PSR?
PHP-FIG означава PHP Framework Interop Group. Групата сама описва целта си като развитие на PHP чрез сътрудничество и стандарти. Зад един PSR следователно не стои производител, а договаряне между проекти, които искат софтуерът им да остане съвместим помежду си.
За вземащите решения ползата е осезаема: ако едно приложение се придържа към интерфейсите на PSR, например библиотеката за логове може да бъде сменена, без да се пипа целият код. Това намалява зависимостта от отделни пакети и изпълнители.
Пътят на един PSR: от Pre-Draft до Accepted
Уставът на PHP-FIG описва твърдо установена последователност:
- Pre-Draft: Изяснява се дали има достатъчно интерес. Формира се работна група, а след успешно гласуване предложението получава номер на PSR.
- Draft: Предложението се разработва, алтернативите и обосновките влизат в мета документ.
- Review: Общността тества спецификацията с пробни реализации, поне четири седмици и докато има две независими, жизнеспособни реализации.
- Accepted: След успешно гласуване PSR е приет; работната група се разпуска.
Освен това има още две състояния. Deprecated означава: приет, но вече не се препоръчва, най-често защото го замества по-нов стандарт. Abandoned означава: вече не се работи по него.
Всички PSR със статус
Състояние според прегледа на PHP-FIG към момента на тази страница:
| № | Заглавие | Статус |
|---|---|---|
| PSR-0 | Autoloading Standard | остарял |
| PSR-1 | Basic Coding Standard | приет |
| PSR-2 | Coding Style Guide | остарял |
| PSR-3 | Logger Interface | приет |
| PSR-4 | Autoloading Standard | приет |
| PSR-5 | PHPDoc Standard | чернова |
| PSR-6 | Caching Interface | приет |
| PSR-7 | HTTP Message Interface | приет |
| PSR-8 | Huggable Interface | изоставен |
| PSR-9 | Security Advisories | изоставен |
| PSR-10 | Security Reporting Process | изоставен |
| PSR-11 | Container Interface | приет |
| PSR-12 | Extended Coding Style Guide | приет |
| PSR-13 | Hypermedia Links | приет |
| PSR-14 | Event Dispatcher | приет |
| PSR-15 | HTTP Handlers | приет |
| PSR-16 | Simple Cache | приет |
| PSR-17 | HTTP Factories | приет |
| PSR-18 | HTTP Client | приет |
| PSR-19 | PHPDoc tags | чернова |
| PSR-20 | Clock | приет |
| PSR-21 | Internationalization | чернова |
| PSR-22 | Application Tracing | чернова |
Най-важните PSR за практиката
- PSR-4 (Autoloading): съпоставя имена на класове с пътища до файлове и е основата на autoloader-а на Composer. Подробности има на страницата Пространства от имена и autoloading.
- PSR-1 и PER Coding Style: общи правила за изписване и форматиране. PER Coding Style според PHP-FIG разширява и заменя PSR-12 и предпоставя PSR-1.
- PSR-3 (Logger): единен интерфейс на логъра в пространството от имена
Psr\Logс осем нива отemergencyдоdebug. - PSR-7, PSR-15, PSR-17, PSR-18 (HTTP): интерфейси за заявки и отговори, middleware, фабрики и HTTP клиенти. Много PHP фреймуърци се основават на тях или предлагат мостове.
- PSR-11 (Container): общ интерфейс за контейнери за dependency injection.
- PSR-6 и PSR-16 (Cache): два интерфейса за междинно съхранение, един подробен и един прост.
- PSR-14 и PSR-20 (събития, часовник): общи интерфейси за събития и за текущото време. Заменяем часовник прави зависимия от времето код, например изтичането на токени, лесно тестваем.
Номерата, между другото, не казват нищо за значението. Те се присъждат при влизане във фазата на черновата, затова остарели и изоставени предложения стоят между важни, приети стандарти.
<?php
use Psr\Log\LoggerInterface;
final class Bestellimport
{
public function __construct(private LoggerInterface $log) {}
public function importieren(string $datei): void
{
try {
// ... обработка на файла ...
} catch (\Throwable $e) {
$this->log->error('Import von {datei} fehlgeschlagen', [
'datei' => basename($datei),
'exception' => $e,
]);
}
}
}
Какво общо имат PSR със сигурността
Няколко стандарта засягат сигурността пряко. PSR-3 определя, че изключенията се подават в контекста под ключа exception, а заместителите като {datei} се заменят със стойности от контекста. При това стойностите не бива да се екранират предварително, защото логърът не знае къде по-късно ще бъдат показани. Който показва логове в уеб интерфейс, трябва да екранира там. Повече има в статията Сигурно записване в лог.
PSR-7 описва HTTP съобщенията като неизменяеми обекти и с UploadedFileInterface::moveTo() предлага единен начин за съхраняване на качени файлове. Спецификацията изисква оригиналният файл след това да бъде премахнат. Проверката на типа на файла и на целевото място остава задача на приложението.
Забележително е, че PSR-9 (Security Advisories) и PSR-10 (Security Reporting Process) бяха изоставени. Така няма общ стандарт за съобщения за сигурност; всеки проект го урежда сам. Как самият проект PHP работи с уязвимостите, описва страницата Как проектът PHP обработва уязвимостите.
Срещу PHP2Shell стандартите не помагат: уязвимостите CVE-2026-109618 и CVE-2026-109619 се намират в интерпретатора. Задължителни са актуализацията до PHP 8.5.12, 8.4.27, 8.3.36 или 8.2.35 и рестартирането на всички PHP процеси.
Как помага PHP SOS конкретно?
- Проверяваме как Вашето приложение записва логове и гарантираме, че изключенията попадат в лога, но не и данни за достъп или идентификатори на сесии.
- Оценяваме как са реализирани качването и HTTP обработката, дори когато минават през библиотеки на PSR-7.
- Изследваме собствените разработки в рамките на одит на сигурността и тест за проникване.
- Внедряваме актуализации на PHP, рестартираме всички worker процеси и документираме състоянието.
Често задавани въпроси
Какво означава PSR?
PSR означава PHP Standards Recommendation. Препоръките се изработват и съгласуват от PHP-FIG, PHP Framework Interop Group. Те са доброволни, но се прилагат от много фреймуърци и библиотеки.
PSR-12 още ли важи?
PSR-12 продължава да се води при PHP-FIG като приет. PHP-FIG обаче публикува с PER Coding Style негов наследник, който според собствените му думи разширява и заменя PSR-12. Там актуалната версия е 3.1.
Има ли PSR за съобщения за сигурност?
Имаше две предложения: PSR-9 за Security Advisories и PSR-10 за процеса на докладване на уязвимости. И двете се водят при PHP-FIG като изоставени. Затова проектите уреждат процеса на докладване сами.
Трябва ли моят проект да спазва PSR?
Не, няма задължение. PSR-4 за autoloading и интерфейси като PSR-3 или PSR-7 обаче значително улесняват използването на чужди пакети и смяната на изпълнители.