1
resposta

FETCH_CLASS

Ola, Em algumas consultas ao banco, vi o professor usando o FETCH_CLASS ao invés do FETCH_ASSOC. Reparei que o código ficou mais enxuto e tentei reproduzir aqui. Ao fazê-lo, o PHP me retornou o erro de falta de parâmetro para o método construtor da classe Student, o que faz sentido. Tentei encontrar uma forma de declarar estes parâmetros, mas não consegui. Se alguém tiver uma ideia, agradeço. Outra dúvida é sobre o FETCH_CLASS. Ele substitui o foreach que fizemos no módulo de PDO? Ele cria diversas instâncias como o foreach para podermos manipular em nossa aplicação? Segue meu código:

Classe PdoStudentRepository

public function selectId(int $id): Student
{
    $statement = $this->connection->prepare("SELECT * FROM students WHERE id = ?;");
    $statement->BindValue(1, $id, \PDO::PARAM_INT);
    $statement->setFetchMode(\PDO::FETCH_CLASS, Student::class);
    $statement->execute();

    return $statement->fetch();
}

Classe Student

    private ?int $id;
    private string $name;
    private \DateTime $birthDate;

    public function __construct(?int $id, string $name, \DateTime $birthDate)
    {
        $this->id = $id;
        $this->name = $name;
        $this->birthDate = $birthDate;
    }

Obrigado

1 resposta

Oi André, beleza?

Você criou essa dúvida dentro do curso de Doctrine, imagino que tenha sido no curso de PDO, é interessante postar no local correto por que dessa maneira temos noção a qual aula se refere. Agora vamos ao conteúdo do tópico:

A constante FETCH_CLASS apenas indica que você vai querer retornar os valores mapeados para uma classe em específica. O problema dessa abordagem é que a classe "não pode" ter um método construtor com parâmetros por que o PHP não saberá como instanciar a classe, se você remover o método construtor e remover o tipo DateTime do $birthDate deve funcionar.

Existe um modo, bastante desconhecido, com a constante PDO::FETCH_FUNC que dá para você instanciar classes com construtores e seus parâmetros através de um método fábrica, ficaria assim :$statement->fetchAll(\PDO::FETCH_FUNC, [Student::class, 'func_instance']). Onde o func_instance é uma método estático da classe Student indicando como deve retornar uma nova instância.

Um exemplo para o func_instance (pode conter erros por que estou criando no momento da resposta mas aí você ajeita):

class Student
{
        //...
        public static function func_instance($id, $name, $date)
        {
            return new self($id, $name, $date);
        }
}

A melhor maneira de mapear os resultados da consulta para um objeto, em minha opinião, é hidratando a classe após obter o resultado da consulta como um array. Se não me engano é desse modo que o Vinicius mostra no curso de PDO.