Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Fatal error: Uncaught Error: Cannot access protected property

Recebi esse erro quanto tentei executar o criar-turma.php:

Stack trace:
#0 C:\Users\victo\Documents\Aulas Alura\Aula PHP\PDO\criar-turma.php(21): Alura\Pdo\Infrastructure\Repository\PdoStudentRepository->save(Object(Alura\Pdo\Domain\Model\Student))
#1 {main}
  thrown in C:\Users\victo\Documents\Aulas Alura\Aula PHP\PDO\src\Infrastructure\Repository\PdoStudentRepository.php on line 54

Fatal error: Uncaught Error: Cannot access protected property Alura\Pdo\Domain\Model\Student::$id in C:\Users\victo\Documents\Aulas Alura\Aula PHP\PDO\src\Infrastructure\Repository\PdoStudentRepository.php:54
Stack trace:
#0 C:\Users\victo\Documents\Aulas Alura\Aula PHP\PDO\criar-turma.php(21): Alura\Pdo\Infrastructure\Repository\PdoStudentRepository->save(Object(Alura\Pdo\Domain\Model\Student))
#1 {main}
  thrown in C:\Users\victo\Documents\Aulas Alura\Aula PHP\PDO\src\Infrastructure\Repository\PdoStudentRepository.php on line 54

O que eu entendi é que na entidade Student.php o id está como privado e não consigo acessar no PdoStudentRepository nessa function:

public function save(Student $student): bool
    {
        if ($student->id === null) {
            return $this->insert($student);
        }

        return $this->update($student);
    }

Quando eu altero o $id em Student.php de private para protected continua com o mesmo erro, apenas como public que o criar-turma.php é executado. Queria saber o que posso fazer para manter o $id privado.

4 respostas

Crie um método público (getter) para retornar o ID. Algo do tipo function getId().

A public function id() em Students.php já não faria isso?

<?php

namespace Alura\Pdo\Domain\Model;

class Student
{
    private ?int $id;
    private string $name;
    private \DateTimeInterface $birthDate;

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

    public function defineId(int $id): void
    {
        if (!is_null($this->id)) {
            throw new \DomainException('Você só pode definir o ID uma vez');
        }
    }

    public function id(): ?int
    {
        return $this->id;
    }

    public function name(): string
    {
        return $this->name;
    }

    public function changeName(string $newName): void
    {
        $this->name = $newName;
    }

    public function birthDate(): \DateTimeInterface
    {
        return $this->birthDate;
    }

    public function age(): int
    {
        return $this->birthDate
            ->diff(new \DateTimeImmutable())
            ->y;
    }
}
solução!

Sim. Entretanto você está usando a propriedade id e não o método id(). Como boa prática o método deveria se chamar getId()

Encontrei meu erro.

em Studenta public function defineId() estava incompleta. Correção:

public function defineId(int $id): void
    {
        if (!is_null($this->id)) {
            throw new \DomainException('Você só pode definir o ID uma vez');
        }

        $this->id = $id;
    }

e em PdoStudentRepository na public function save() estava passando a propriedade em vez do método, como foi apontado. Correto:

public function save(Student $student): bool
    {
        if ($student->getId() === null) {
            return $this->insert($student);
        }

        return $this->update($student);
    }

Utilizando as boas praticas como você mencionou ajuda bastante a não ter confusão. Obrigado!