π» ΠΡΠΎΠ΅ΠΊΡΠ½ΡΠ΅ ΠΊΠΎΠ΄-ΡΡΠΈΠ»ΠΈ
π€ ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅β
π ΠΠ±ΡΠΈΠ΅ ΠΏΡΠ°Π²ΠΈΠ»Π°β
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ camelCase Π΄Π»Ρ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ .
- ΠΠΎΠ΄Π±ΠΈΡΠ°Π΅ΠΌ ΠΎΡΠΌΡΡΠ»Π΅Π½Π½ΡΠ΅ ΠΈΠΌΠ΅Π½Π°, ΠΎΡΡΠ°ΠΆΠ°ΡΡΠΈΠ΅ Ρ ΡΠ°Π½ΠΈΠΌΡΠ΅ Π΄Π°Π½Π½ΡΠ΅.
- Boolean ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΈΠ»ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π°ΡΠΈΠ½Π°Π΅ΠΌ Ρ is/has.
$userRole = $this->user->role;
$requestData = $request->getData();
$isAdminUser = $userRole === 'admin';
π ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΊΠ»Π°ΡΡΠ°β
- ΠΡΠ΅Π³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ protected.
- Π―Π²Π½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ .
protected string $userName;
protected string $email;
public function __construct(string $userName, string $email)
{
$this->userName = $userName;
$this->email = $email;
}
π ΠΠ»ΡΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²β
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ snake_case:
return [
'user_role' => $userRole,
'request_data' => $requestData,
'is_admin_user' => $isAdminUser,
];
π₯ ΠΠΎΠ½ΡΡΠ°Π½ΡΡβ
- ΠΡΠ΅Π³Π΄Π° ΠΊΠ°ΠΏΡΠΎΠΌ (
SNAKE_CASE). - ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ Π΄ΠΎΡΡΡΠΏΠ°.
public const USER_ROLE_KEY = 'user_role';
π Π€ΡΠ½ΠΊΡΠΈΠΈβ
β ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΡβ
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ camelCase.
- ΠΠΎΠ΄Π±ΠΈΡΠ°Π΅ΠΌ Π½Π°Π·Π²Π°Π½ΠΈΡ ΠΏΠΎ ΡΠΌΡΡΠ»Ρ.
- Boolean-ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΠ΅ΡΠ΅Π· is/has.
- Π‘Π»Π΅Π΄ΡΠ΅ΠΌ ΡΡ Π΅ΠΌΠ΅ Π³Π»Π°Π³ΠΎΠ» + ΡΡΡΠ΅ΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅.
- ΠΡΠ΅Π³Π΄Π° ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ ΡΠΈΠΏ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ.
public function getUserRole(User $user): ?string
{
return $user->role ?? null;
}
π ΠΠΏΠ΅ΡΠ°ΡΠΎΡΡ Π²Π΅ΡΠ²Π»Π΅Π½ΠΈΡβ
β ΠΠΈΠ½ΠΈΠΌΠΈΠ·Π°ΡΠΈΡ Π»ΠΎΠ³ΠΈΠΊΠΈ Π²Π½ΡΡΡΠΈ ifβ
// β ΠΠ»ΠΎΡ
ΠΎ
if ($user) {
// ΡΠ»ΠΎΠΆΠ½Π°Ρ Π»ΠΎΠ³ΠΈΠΊΠ°
} else {
throw new Exception;
}
return $user;
// β
Π₯ΠΎΡΠΎΡΠΎ
if (!$user) {
throw new Exception;
}
// ΡΠ»ΠΎΠΆΠ½Π°Ρ Π»ΠΎΠ³ΠΈΠΊΠ°
return $user;
β ΠΠ·Π±Π΅Π³Π°Π΅ΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΡ
if ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ matchβ
// β ΠΠ»ΠΎΡ
ΠΎ
function getGradeComment($grade) {
if ($grade === 'A') return 'Excellent';
if ($grade === 'B') return 'Good';
if ($grade === 'C') return 'Average';
return 'Invalid Grade';
}
// β
Π₯ΠΎΡΠΎΡΠΎ
function getGradeComment($grade) {
return match ($grade) {
'A' => 'Excellent',
'B' => 'Good',
'C' => 'Average',
default => 'Invalid Grade',
};
}
π ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ½ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ (SOLID)β
π― ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΡβ
- S (Single Responsibility) β ΠΎΠ΄ΠΈΠ½ ΠΊΠ»Π°ΡΡ = ΠΎΠ΄Π½Π° Π·Π°Π΄Π°ΡΠ°.
- O (Open/Closed) β ΠΊΠ»Π°ΡΡΡ ΠΎΡΠΊΡΡΡΡ Π΄Π»Ρ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ, Π½ΠΎ Π·Π°ΠΊΡΡΡΡ Π΄Π»Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ.
- D (Dependency Inversion) β Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ.
π ΠΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΡ (Controller)β
- ΠΠΎΠ½ΡΡΠΎΠ»Π»Π΅Ρ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ Ρ ΡΠ΅ΠΊΠ²Π΅ΡΡΠΎΠΌ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅ΡΠΏΠΎΠ½Ρ.
- ΠΠ°ΡΠ΅Π³ΠΎΡΠΈΡΠ΅ΡΠΊΠΈ ΠΈΠ·Π±Π΅Π³Π°Π΅ΠΌ Π»ΠΎΠ³ΠΈΠΊΠΈ Π² ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ΅!
class TitlesTableController extends Controller
{
public function __construct(protected readonly TitlesTableServiceInterface $service) {}
public function index(): JsonResponse
{
try {
return response()->json($this->service->getTitlesTableData());
} catch (Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
}
π Π‘Π΅ΡΠ²ΠΈΡΡ (Service)β
- Π‘ΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΡ.
- ΠΠ°ΠΏΡΠΎΡΡ ΠΊ ΠΠ ΡΠ΅ΡΠ΅Π·
Repository.
class TitlesTableService implements TitlesTableServiceInterface
{
public function __construct(protected TitlesTableRepositoryInterface $repository) {}
public function getTitlesTableData(): array
{
return $this->repository->getTitles()->toArray();
}
}
π UseCase vs Serviceβ
- UseCase β ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 1 ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄
handle(). - Service β Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π»ΠΎΠ³ΠΈΠΊΡ, ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ Π² ΡΠ°Π·Π½ΡΡ ΠΌΠ΅ΡΡΠ°Ρ .
class CheckCaptchaUseCase
{
public function handle(?string $token): bool
{
return $this->validateCaptcha($token);
}
}
π¦ DTO (Data Transfer Object)β
- DTO β ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π°Π½Π½ΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ»ΠΎΡΠΌΠΈ.
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ
SerializedNameΠ΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ.
#[SerializedName('email')]
protected string $email;
π ENUMβ
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ enum Π²ΠΌΠ΅ΡΡΠΎ ΡΡΡΠΎΠΊΠΎΠ²ΡΡ
Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ:
enum UserStatus: string
{
case ACTIVE = 'active';
case BANNED = 'banned';
}
β‘ ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡβ
- ΠΠ΅ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΡΠΉ ΠΏΡΠ΅ΠΆΠ΄Π΅Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ!
- Π‘ΠΌΠΎΡΡΠΈ Π½Π° Π·Π°ΠΏΡΠΎΡΡ β ΠΈΠ·Π±Π΅Π³Π°ΠΉ
N+1! - ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ batch-Π·Π°ΠΏΡΠΎΡΡ.
π ΠΡΠΎΠ³β
ΠΡΠΎΡ ΡΡΠΈΠ»Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ ΠΊΠΎΠ΄Π° Π΄Π΅Π»Π°Π΅Ρ Π΅Π³ΠΎ ΡΠΈΡΠ°Π΅ΠΌΡΠΌ, ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΡΠ΅ΠΌΡΠΌ ΠΈ Π»Π΅Π³ΠΊΠΈΠΌ Π² ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ΅.