# 07. Типизация и строгость

[← Оглавление](./index.md)

---

## declare(strict_types=1) — обязательно в каждом файле

**ПЛОХО — НЕЯВНОЕ ПРИВЕДЕНИЕ ТИПОВ**
```php
<?php
// нет strict_types — PHP молча приведёт "5" к int
function add(int $a, int $b): int {
    return $a + $b;
}
echo add("5", "10"); // 15 — ошибка замаскирована
```

**ХОРОШО — ЯВНЫЙ TYPEERROR ПРИ НЕВЕРНЫХ ТИПАХ**
```php
<?php
declare(strict_types=1);

function add(int $a, int $b): int {
    return $a + $b;
}
echo add("5", "10"); // TypeError — сразу видим проблему
```

---

## Типизация свойств, аргументов и возвращаемых значений

**ПЛОХО — PHPDOC ВМЕСТО НАТИВНОЙ ТИПИЗАЦИИ**
```php
class ClientInfo {
    /** @var string|null */
    private $name;
    
    public function setName($name) {
        $this->name = $name;
    }
    
    public function getName() {
        return $this->name;
    }
}
```

**ХОРОШО — НАТИВНАЯ ТИПИЗАЦИЯ PHP 8**
```php
class ClientInfo {
    private ?string $name = null;
    
    public function setName(string $name): void {
        $this->name = $name;
    }
    
    public function getName(): ?string {
        return $this->name;
    }
}
```

---

## readonly классы для DTO (PHP 8.2+)

**ПЛОХО — ИЗМЕНЯЕМЫЙ МАССИВ ВМЕСТО DTO**
```php
function updateClient(int $id, array $data): void {
    $client = $this->getById($id);
    $client['NAME'] = $data['NAME'] ?? $client['NAME'];
    // легко ошибиться с ключом, нет типобезопасности
}
```

**ХОРОШО — НЕИЗМЕНЯЕМЫЙ READONLY DTO**
```php
readonly class UpdateClientDto {
    public function __construct(
        public string $name,
        public ?string $phone = null,
        public ?string $email = null,
    ) {}
}

function updateClient(int $id, UpdateClientDto $dto): void {
    $client = $this->getById($id);
    $client->setName($dto->name);
}
```