0
respostas

Erro ao listar telefones (erro no insert do SQLITE ?).

Após seguir os passos da aula, ao executar o arquivo de "listar-alunos", ele me reportou o seguinte erro:

PHP Notice: Undefined variable: phone in D:\Alura\PHP\php-pdo\src\Infraestructure\Repository\PdoStudentRepository.php on line 65

Notice: Undefined variable: phone in D:\Alura\PHP\php-pdo\src\Infraestructure\Repository\PdoStudentRepository.php on line 65PHP Fatal error: Uncaught TypeError: Argument 1 passed to Alura\Pdo\Domain\Model\Student::addPhone() must be an instance of Alura\Pdo\Domain\Model\Phone, null given, called in D:\Alura\PHP\php-pdo\src\Infraestructure\Repository\PdoStudentRepository.php on line 65 and defined in D:\Alura\PHP\php-pdo\src\Domain\Model\Student.php:56

Com testes, percebi que aparentemente o insert do arquivo de conexão não funcionou, pois ao listar os alunos sem chamar a função "fillphonesOf" ele reporta:

( ["phones":"Alura\Pdo\Domain\Model\Student":private]=> array(0) { } )

para o aluno com "id = 1".

Conexão:

<?php

$databasePath = __DIR__ . '/banco.sqlite';
$pdo = new PDO('sqlite:' . $databasePath);

echo 'connected';

$pdo->exec("INSERT INTO phones (area_code, number, student_id) VALUES ('41', '33333334', 1), ('41', '999998888', 1);");
exit();

PDOStudentRepository:

<?php

namespace Alura\Pdo\Infraestructure\Repository;

use Alura\Pdo\Domain\Model\Phone;
use Alura\Pdo\Domain\Model\Student;
use Alura\Pdo\Domain\Repository\StudentRepository;
use PDO;
use RuntimeException;

class PdoStudentRepository implements StudentRepository
{
    private PDO $connection;

    public function __construct(PDO $connection)
    {
        $this->connection = $connection;
    }

    public function allStudents(): array
    {
        $sqlQuery = 'SELECT * FROM students;';
        $stmt = $this->connection->query($sqlQuery);

        return $this->hydrateStudentList($stmt);

    }

    private function hydrateStudentList(\PDOStatement $stmt): array
    {
        $studentDataList = $stmt->fetchAll();

        $studentList = [];

        foreach ($studentDataList as $studentData) {
            $student = new Student(
                $studentData['id'],
                $studentData['name'],
                new \DateTimeImmutable($studentData['birth_date'])
            );

            $this->fillPhonesOf($student);

            $studentList[] = $student;
        }

        return $studentList;
    }

    private function fillPhonesOf(Student $student): void
    {
        $sqlQuery = 'SELECT id, area_code, number FROM phones WHERE student_id = ?';
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(1, $student->id(), PDO::PARAM_INT);
        $stmt->execute();

        $phoneDataList = $stmt->fetchAll();
        foreach($phoneDataList as $phoneData) {
            $phone = new Phone(
                $phoneData['id'],
                $phoneData['area_code'],
                $phoneData['number']);
        }

        $student->addPhone($phone);

    }

    public function studentsBirthAt(\DateTimeInterface $birthDate): array
    {
        $sqlQuery = 'SELECT * FROM students WHERE birth_date = ?;';
        $stmt = $this->connection->prepare($sqlQuery);
        $stmt->bindValue(1, $birthDate->format('Y-m-d'));
        $stmt->execute();

        return $this->hydrateStudentList($stmt);
    }

Student:

<?php

namespace Alura\Pdo\Domain\Model;

class Student
{
    private ?int $id;
    private string $name;
    private \DateTimeInterface $birthDate;
    /** @var Phone[] */
    private array $phones = [];

    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');
        }

        $this->id = $id;
    }

    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;
    }

    public function addPhone(Phone $phone): void
    {
        $this->phones[] = $phone;
    }

    /** @return Phone[] */
    public function phones(): array
    {
        return $this->phones();
    }
}