PSR standartlari — kod uslubi va autoload

~12 daq · PHP · Zamonaviy PHP

Muammodan boshlaylik

Jamoada uchta dasturchi:

  • Biri function getUser() yozadi, ikkinchisi function get_user(), uchinchisi function GetUser()
  • Biri 2 bo'sh joy bilan chekinadi, boshqasi tab bilan
  • Biri { ni shu qatorda, boshqasi keyingi qatorda qo'yadi

Har bir Pull Request da yarim izohlar "bu yerda bo'sh joy yetishmayapti" haqida. Git diff da haqiqiy o'zgarish o'rniga yuzlab formatlash o'zgarishlari.

Bundan tashqari: siz yozgan logger classini Laravel loyihasida ishlatib bo'lmaydi, chunki Laravel boshqa logger interfeysini kutadi.

PSR (PHP Standards Recommendations) — PHP jamiyati qabul qilgan umumiy kelishuvlar. Ularni PHP-FIG guruhi (Laravel, Symfony, Composer, Drupal va boshqa loyihalar vakillari) ishlab chiqadi.


Eng muhim PSR lar

PSR Nima haqida
PSR-1 Asosiy kod standarti
PSR-12 / PER-CS Kod uslubi (formatlash)
PSR-4 Autoload — namespace va papka mosligi
PSR-3 Logger interfeysi
PSR-7 HTTP so'rov va javob interfeysi
PSR-11 Konteyner (DI) interfeysi
PSR-15 HTTP middleware
PSR-18 HTTP mijoz interfeysi

Boshlang'ich darajada eng muhimlari — PSR-1, PSR-12, PSR-4.


PSR-1 va PSR-12 — kod uslubi

Nomlash

<?php

declare(strict_types=1);

namespace Dokon\Tolov;           // namespace — PascalCase

use Dokon\Model\Buyurtma;

final class PaymeTolov            // Class — PascalCase
{
    public const MAKS_SUMMA = 50_000_000;   // Konstanta — KATTA_HARF

    private string $merchantId;              // Xususiyat — camelCase

    public function tolovYarat(Buyurtma $buyurtma): string   // Metod — camelCase
    {
        $tranzaksiyaId = $this->idYasash();  // O'zgaruvchi — camelCase
        return $tranzaksiyaId;
    }

    private function idYasash(): string
    {
        return bin2hex(random_bytes(8));
    }
}
Nima Uslub Misol
Class, interface, trait, enum PascalCase BuyurtmaXizmati
Metod camelCase tolovYarat()
Konstanta UPPER_SNAKE MAKS_SUMMA
Xususiyat, o'zgaruvchi camelCase (kelishuv) $tranzaksiyaId

Formatlash qoidalari

  • Chekinish — 4 bo'sh joy, tab emas
  • Class va metod uchun { — keyingi qatorda
  • if, for, foreach uchun { — shu qatorda
  • Kalit so'zdan keyin bo'sh joy: if (, foreach (; funksiya nomidan keyin — yo'q: strlen(
  • Faqat PHP bo'lgan faylda yopuvchi ?> yozilmaydi
  • Fayl bitta bo'sh qator bilan tugaydi
  • Bitta qator — 120 belgidan oshmasin (tavsiya)
<?php

if ($a === $b) {
    echo 'teng';
} elseif ($a > $b) {
    echo 'katta';
} else {
    echo 'kichik';
}

foreach ($mahsulotlar as $kalit => $mahsulot) {
    // ...
}

$natija = match ($holat) {
    'new' => 'Yangi',
    default => 'Boshqa',
};

[!INFO] PSR-12 ning yangilangan, zamonaviy PHP imkoniyatlarini (enum, match, readonly) qamraydigan davomi — PER Coding Style. Qoidalari deyarli bir xil.


Avtomatik formatlash

Qoidalarni qo'lda kuzatish shart emas. Vositalar buni avtomatik qiladi:

PHP CS Fixer

composer require --dev friendsofphp/php-cs-fixer
vendor/bin/php-cs-fixer fix src --rules=@PER-CS

Butun src/ papkasini bir zumda formatlaydi.

Laravel Pint

Laravel loyihalarida standart:

composer require --dev laravel/pint
vendor/bin/pint

Muharrirda

VS Code da PHP Intelephense yoki "php cs fixer" kengaytmasi faylni saqlaganda avtomatik formatlaydi.

Qoida: jamoada formatlash haqida bahslashmang — vositani sozlang va u hal qilsin. Formatlashni CI ga (GitHub Actions) qo'shing — noto'g'ri formatlangan kod main ga tushmaydi.


PSR-4 — autoload

33-darsda ko'rdik: namespace prefiksi papkaga mos keladi.

"autoload": {
    "psr-4": {
        "Dokon\\": "src/"
    }
}
Dokon\Tolov\PaymeTolov  →  src/Tolov/PaymeTolov.php

Qoidalar:

  • Bir fayl — bir class
  • Fayl nomi aynan class nomi bilan bir xil (harflarning katta-kichikligi ham)
  • Namespace papka tuzilmasiga to'liq mos

PSR-3 — interfeyslar nima uchun standartlashtiriladi

PSR-3 LoggerInterface ni belgilaydi:

<?php

namespace Psr\Log;

interface LoggerInterface
{
    public function error(string|\Stringable $message, array $context = []): void;
    public function warning(string|\Stringable $message, array $context = []): void;
    public function info(string|\Stringable $message, array $context = []): void;
    // ...
}

Endi sizning kodingiz aniq loggerga emas, standart interfeysga bog'lanadi:

<?php

use Psr\Log\LoggerInterface;

class BuyurtmaXizmati
{
    public function __construct(private LoggerInterface $logger) {}

    public function rasmiylashtirish(int $id): void
    {
        $this->logger->info('Buyurtma rasmiylashtirildi', ['id' => $id]);
    }
}

Monolog, Laravel logger, Symfony logger — hammasi LoggerInterface ni amalga oshiradi. Sizning classingiz ularning istalgani bilan ishlaydi. Bu 31-darsdagi interface g'oyasining butun ekotizim darajasidagi qo'llanilishi.


Nima uchun shunday?

Nima uchun kod uslubi muhim — kompyuterga baribir-ku?

Kod yozilganidan ko'ra o'n barobar ko'p o'qiladi. Bir xil uslub — miya formatni emas, mantiqni o'qishi demak. Siz Laravel manbasini, Symfony kutubxonasini, hamkasbingiz kodini va 6 oy oldin o'zingiz yozgan kodni bir xil tezlikda o'qiysiz. Git diff larda faqat haqiqiy o'zgarishlar ko'rinadi. Va kod reviewda vaqt muhim narsalarga sarflanadi.


Xulosa

Eslab qoling:

  • PSR — PHP jamiyatining umumiy standartlari (PHP-FIG)
  • Class — PascalCase, metod va o'zgaruvchi — camelCase, konstanta — UPPER_SNAKE
  • 4 bo'sh joy; class/metod { keyingi qatorda, if/for { shu qatorda
  • Formatlashni qo'lda emas — PHP CS Fixer yoki Pint bilan
  • PSR-4 — namespace va papka mosligi
  • PSR-3, PSR-7 va boshqalar — kutubxonalar bir-biri bilan ishlashi uchun umumiy interfeyslar

Keyingi dars

41-dars: MVC arxitektura — oddiy router va controller yozish