Files
interview-demo-code/.cursor/rules/php.md
Nikita Kiselev 393bbb286b
Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
Squashed commit message
2026-03-11 23:00:59 +03:00

244 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PHP Code Style Rules
## PHP Version
The project supports PHP 7.4+
## PSR Standards
- **PSR-1**: Basic Coding Standard
- **PSR-4**: Autoloading Standard
- **PSR-12**: Extended Coding Style
## Code Style
### Type Declarations
```php
// ✅ Correct strict typing
public function getCustomers(Request $request): JsonResponse
{
$id = (int) $request->get('id');
return new JsonResponse(['data' => $customers]);
}
// ❌ Incorrect no types
public function getCustomers($request)
{
return ['data' => $customers];
}
```
### Nullable Types
```php
// ✅ Correct
public function findById(?int $id): ?array
{
if ($id === null) {
return null;
}
return $this->query->where('id', '=', $id)->firstOrNull();
}
```
### Strict Types
Always use `declare(strict_types=1);`:
```php
<?php
declare(strict_types=1);
namespace App\Services;
```
### Array Syntax
```php
// ✅ Preferred short syntax
$array = ['key' => 'value'];
// ❌ Do not use
$array = array('key' => 'value');
```
### String Interpolation
```php
// ✅ Preferred
$message = "User {$userId} not found";
// ✅ Alternative
$message = sprintf('User %d not found', $userId);
```
### Arrow Functions (PHP 7.4+)
```php
// ✅ For simple operations
$filtered = array_filter($items, fn($item) => $item->isActive());
// ❌ For complex logic use regular functions
```
### Nullsafe Operator (PHP 8.0+)
```php
// ✅ For 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 with visibility modifier
private string $tableName;
private Builder $builder;
```
## Documentation
### PHPDoc
```php
/**
* @throws ValidationException If parameters are invalid
*/
public function getCustomers(Request $request): JsonResponse
{
// ...
}
```
### Inline Comments
```php
// ✅ Useful comments
// Apply filters to calculate total number of records
$countQuery = $this->buildCountQuery($filters);
// ❌ Obvious comments
// Get data
$data = $this->getData();
```
## Error Handling
### Exceptions
```php
// ✅ Specific exceptions
if (!$userId) {
throw new InvalidArgumentException('User ID is required');
}
// ✅ Logging
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
// ✅ Correct
$customers = $this->builder->newQuery()
->select(['id', 'name', 'email'])
->from('acmeshop_customers')
->where('status', '=', 'active')
->orderBy('created_at', 'DESC')
->get();
// In edge cases raw SQL may be used
$result = $this->database->query("SELECT * FROM acmeshop_customers");
```
### Parameter Binding
```php
// ✅ Query Builder automatically binds parameters
$query->where('name', 'LIKE', "%{$search}%");
// ❌ Never concatenate values into SQL, avoid SQL Injection.
```
## Array Access
### Safe Array Access
```php
// ✅ Use Arr::get()
use Acme\ECommerceFramework\Support\Arr;
$value = Arr::get($data, 'key', 'default');
// ❌ Unsafe
$value = $data['key']; // may trigger an error
```
## Return Types
```php
// ✅ Always specify return type
public function getData(): array {}
public function findById(int $id): ?array {}
public function process(): void {}
// ❌ Without type
public function getData() {}
```
## Visibility Modifiers
```php
// ✅ Always specify visibility modifier
private string $tableName;
protected Builder $builder;
public function getData(): array {}
```