# PHP Code Style Rules ## PHP Version Проект поддерживает PHP 7.4+ ## PSR Standards - **PSR-1**: Basic Coding Standard - **PSR-4**: Autoloading Standard - **PSR-12**: Extended Coding Style ## Code Style ### Type Declarations ```php // ✅ Правильно - строгая типизация public function getCustomers(Request $request): JsonResponse { $id = (int) $request->get('id'); return new JsonResponse(['data' => $customers]); } // ❌ Неправильно - без типов public function getCustomers($request) { return ['data' => $customers]; } ``` ### Nullable Types ```php // ✅ Правильно public function findById(?int $id): ?array { if ($id === null) { return null; } return $this->query->where('id', '=', $id)->firstOrNull(); } ``` ### Strict Types Всегда используй `declare(strict_types=1);`: ```php 'value']; // ❌ Не использовать $array = array('key' => 'value'); ``` ### String Interpolation ```php // ✅ Предпочтительно $message = "User {$userId} not found"; // ✅ Альтернатива $message = sprintf('User %d not found', $userId); ``` ### Arrow Functions (PHP 7.4+) ```php // ✅ Для простых операций $filtered = array_filter($items, fn($item) => $item->isActive()); // ❌ Для сложной логики - используй обычные функции ``` ### Nullsafe Operator (PHP 8.0+) ```php // ✅ Для PHP 7.4 $name = $user && $user->profile ? $user->profile->name : null; ``` ## Naming Conventions ### Classes ```php // ✅ PascalCase class TelegramCustomerService {} class UserRepository {} ``` ### Methods ```php // ✅ camelCase public function getCustomers(): array {} public function saveOrUpdate(array $data): array {} ``` ### Variables ```php // ✅ camelCase $customerData = []; $totalRecords = 0; ``` ### Constants ```php // ✅ UPPER_SNAKE_CASE private const MAX_RETRIES = 3; public const DEFAULT_PAGE_SIZE = 20; ``` ### Private Properties ```php // ✅ camelCase с модификатором доступа private string $tableName; private Builder $builder; ``` ## Documentation ### PHPDoc ```php /** * @throws ValidationException Если параметры невалидны */ public function getCustomers(Request $request): JsonResponse { // ... } ``` ### Inline Comments ```php // ✅ Полезные комментарии // Применяем фильтры для подсчета общего количества записей $countQuery = $this->buildCountQuery($filters); // ❌ Очевидные комментарии // Получаем данные $data = $this->getData(); ``` ## Error Handling ### Exceptions ```php // ✅ Специфичные исключения if (!$userId) { throw new InvalidArgumentException('User ID is required'); } // ✅ Логирование try { $result = $this->service->process(); } catch (Exception $e) { $this->logger->error('Processing failed', [ 'exception' => $e, 'context' => $context, ]); throw new ProcessingException('Failed to process', 0, $e); } ``` ## Query Builder Usage ### Always Use Query Builder ```php // ✅ Правильно $customers = $this->builder->newQuery() ->select(['id', 'name', 'email']) ->from('acmeshop_customers') ->where('status', '=', 'active') ->orderBy('created_at', 'DESC') ->get(); // В крайних случаях можно использовать прямые SQL $result = $this->database->query("SELECT * FROM acmeshop_customers"); ``` ### Parameter Binding ```php // ✅ Query Builder автоматически биндит параметры $query->where('name', 'LIKE', "%{$search}%"); // ❌ Никогда не конкатенируй значения в SQL, избегай SQL Injection. ``` ## Array Access ### Safe Array Access ```php // ✅ Используй Arr::get() use Acme\ECommerceFramework\Support\Arr; $value = Arr::get($data, 'key', 'default'); // ❌ Небезопасно $value = $data['key']; // может вызвать ошибку ``` ## Return Types ```php // ✅ Всегда указывай return type public function getData(): array {} public function findById(int $id): ?array {} public function process(): void {} // ❌ Без типа public function getData() {} ``` ## Visibility Modifiers ```php // ✅ Всегда указывай модификатор доступа private string $tableName; protected Builder $builder; public function getData(): array {} ```