Где происходит фильтрация и валидация данных в приложении?

«Где происходит фильтрация и валидация данных в приложении?» — вопрос из категории Архитектура, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Фильтрация (санация) и валидация данных должны происходить на нескольких уровнях для обеспечения безопасности и целостности данных (Defense in Depth).

1. Уровень представления (клиентская сторона):

  • HTML5-валидация (required, type="email", pattern) для улучшения UX.
  • JavaScript-валидация для мгновенной обратной связи.
  • Важно: Это ненадежно, так как легко отключается, и служит только для удобства пользователя.

2. Уровень транспорта (сервер, точка входа): Это ключевой уровень. Входящие данные (HTTP-запросы) должны быть проверены и очищены перед передачей в бизнес-логику.

  • Валидация: Проверка формата, обязательности, диапазонов, корректности бизнес-правил.
  • Фильтрация: Очистка от потенциально опасных символов (XSS).

    // Пример с использованием Symfony Validator и санитизатора
    class UserRegistrationData
    {
        #[AssertNotBlank]
        #[AssertEmail]
        private string $email;
    
        #[AssertNotBlank]
        #[AssertLength(min: 8, max: 50)]
        #[AssertRegex(pattern: '/^(?=.*[a-z])(?=.*[A-Z])(?=.*d).+$/')]
        private string $password;
    }
    
    // В контроллере
    $data = new UserRegistrationData();
    $data->email = filter_var($request->get('email'), FILTER_SANITIZE_EMAIL);
    $data->password = $request->get('password'); // Пароли не санитизируют
    
    $errors = $validator->validate($data);
    if (count($errors) > 0) { ... }

3. Уровень бизнес-логики (доменный слой):

  • Инварианты предметной области проверяются внутри сущностей (Entities) или доменных сервисов.
    class Order {
        private function __construct(private float $amount) {
            if ($amount <= 0) {
                throw new DomainException('Order amount must be positive.');
            }
        }
    }

4. Уровень persistence (база данных):

  • Использование подготовленных выражений (Prepared Statements) для защиты от SQL-инъекций.
  • Ограничения на уровне схемы БД (NOT NULL, UNIQUE, CHECK).

5. Уровень вывода (View/Template):

  • Экранирование (escaping) всех пользовательских данных при выводе в HTML, JSON, XML для защиты от XSS.
    // В шаблоне Twig экранирование включено по умолчанию
    <p>Welcome, {{ user.username }}!</p>

Итог: Валидация и фильтрация — это непрерывный процесс, а не одноразовое действие в контроллере.