Aplicação 3: Validador de Dados DTO com Atributos PHP 8

Um dos maiores erros em projetos WordPress é o uso direto de $_POST ou $_GET dentro da lógica de negócio.
Isso cria brechas de segurança e dificulta a manutenção do código.
Nesta aplicação, vamos construir um micro-framework de validação baseado em Data Transfer Objects (DTOs).
A ideia é transformar os dados brutos da requisição em objetos tipados e validados antes que eles cheguem ao seu Service Layer.
Isso segue rigorosamente os princípios de Clean Code e SOLID.
Vamos utilizar Atributos do PHP 8 para definir as regras de validação.

Definindo Atributos de Validação Customizados

Atributos permitem que adicionemos metadados às propriedades de uma classe.
Criaremos um atributo Email e outro MinLength.
A vantagem é que a lógica de validação fica desacoplada da estrutura do dado.
Sempre que você precisar de uma nova regra, basta criar uma nova classe de Atributo.
Didaticamente, isso torna o seu código modular e extremamente fácil de testar.

#[Attribute]
class Required {}

#[Attribute]
class Email {}

class UserRegistrationDTO {
    #[Required]
    public string $username;

    #[Email]
    public string $email;
}

Agora, criaremos o motor de validação que utiliza a Reflection API do PHP para ler esses atributos.
A Reflection API permite que o código inspecione a si mesmo em tempo de execução.
Embora tenha um pequeno custo de performance, o ganho em segurança e clareza é imenso.
Seniores costumam cachear esses metadados para garantir que a validação seja instantânea em ambientes de produção.

class Validator {
    public static function validate(object $dto): array {
        $errors = [];
        $reflection = new ReflectionClass($dto);
        
        foreach ($reflection->getProperties() as $property) {
            $attributes = $property->getAttributes();
            foreach ($attributes as $attr) {
                $rule = $attr->getName();
                $value = $property->getValue($dto);
                
                if ($rule === 'Required' && empty($value)) {
                    $errors[$property->getName()] = "Campo obrigatório.";
                }
                if ($rule === 'Email' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
                    $errors[$property->getName()] = "E-mail inválido.";
                }
            }
        }
        return $errors;
    }
}

O uso prático disso no seu plugin WordPress é transformador.
No seu controller de API, você apenas instancia o DTO com os dados do wp_unslash() e chama o Validator::validate().
Se houver erros, você retorna um WP_REST_Response com status 400.
Se estiver limpo, você passa um objeto seguro para sua função de salvamento no banco.
Isso elimina o risco de SQL Injection e XSS logo na entrada dos dados.
O MundoPHP foca em ensinar padrões que duram décadas.

Rolar para cima