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

Uncaught Error: Call to a member function execute() on bool ... ja vi 2 perguntas com este erro no forum mas nao resolveram meu problema

Boa noite, ao executar o arquivo criar-turma.php obtive o erro:

PHP Fatal error:  Uncaught Error: Call to a member function execute() on bool in C:\xampp\htdocs\phppdo\src\Domain\Infrastructure\Repository\PdoStudentRepository.php:66
Stack trace:
#0 C:\xampp\htdocs\phppdo\src\Domain\Infrastructure\Repository\PdoStudentRepository.php(55): Alura\Pdo\Domain\Infrastructure\Repository\PdoStudentRepository->insert(Object(Alura\Pdo\Domain\Model\Student))
#1 C:\xampp\htdocs\phppdo\criar-turma.php(17): Alura\Pdo\Domain\Infrastructure\Repository\PdoStudentRepository->save(Object(Alura\Pdo\Domain\Model\Student))

Observação, minha tabela students já está criada, Se alguem puder dar uma olhada nos meus codigos e ver se bate o olho em algum possivel erro... muito obrigada.

criar-turma.php

<?php
.....

$connection = ConnectionCreator::createConnection();
$studentRepository = new PdoStudentRepository($connection);

$connection->beginTransaction();
$aStudent = new Student(null, 'Nico Steppat', new DateTimeImmutable('1985-05-01')); 
$studentRepository->save($aStudent);
$anotherStudent = new Student(null, 'Sergio Lopes', new DateTimeImmutable('1985-05-01'));
$studentRepository->save($anotherStudent);

$connection->commit(); 

PdoStudentRepository

<?php

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

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

    private function hydrateStudentList(\PDOStatement $stmt): array
    {
        $studentDataList = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $studentList = [];

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

        return $studentList;
    }

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

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

    private function insert(Student $student): bool
    {
        $insertQuery = 'INSERT INTO students (name, birth_date) VALUES (:name, :birth_date);';  
        $stmt = $this->connection->prepare($insertQuery);

        $success = $stmt->execute([                            ->> o erro aponta pra esta linha....
            ':name' => $student->name(),
            ':birth_date' => $student->birthDate()->format('Y-m-d'),
        ]);

        if ($success) {
            $student->defineId($this->connection->lastInsertId());
        }

        return $success;
    }

    private function update(Student $student): bool
    {
        omiti pra caber....
    }

    public function remove(Student $student): bool
    {
        $stmt = $this->connection->prepare('DELETE FROM students WHERE id = ?;');
        $stmt->bindValue(1, $student->id(), PDO::PARAM_INT);

        return $stmt->execute();
    }
}

Student.php

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

        $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;
    }
}
3 respostas
solução!

Olá, Cristina. No capítulo 6 nós vamos falar sobre como lidar com erros e investigar problemas, mas vou te adiantar um detalhezinho. O método prepare pode retornar false em caso de erro ao montar a query. Esse erro pode acontecer por diversos motivos (banco fora do ar, query incorreta, etc).

Há formas melhores de se identificar o erro (vamos aprender no capítulo 6), mas por enquanto, adicione a seguinte linha antes da linha onde você indicou que o erro acontece:

var_dump($this->connection->errorInfo()[2]);
exit();

Isso vai exibir no terminal uma mensagem de erro indicando exatamente o que aconteceu de errado. A partir daí nós podemos ver como corrigir o problema. :-D

Oi Vinicius, fazendo isso ele detalhou melhor erro:

"no such table: students"

sei que ela existe pois quando executo o arquivo lista-alunos ela aparece

mas a neste arquivo lista-alunos se conecta ao sqlite desta forma ainda:

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

fiz um teste e mexi no arquivo ConnectionCreator.php pra ver se poderia ser problema na conexao..mas ao mexer la executei novamente o criar-turma e apareceu NULL

voltei ao que estava antes e apareceu de novo "no such table: students"

Irei assistir ao capitulo de erros, mas se você bater o olho nesta mensagem e souber/ou imaginar o que pode estar causando este erro me fala por favor.

Muito obrigada!!!!

agora descobri melhor o problema....

como tinha dado null quando mexi no ConnectionCreator.php ...depois que pensei que null poderia ser porque não retornou erro algum (as vezes nao tem nada a ver este null pode ser outra coisa né) mas resolvi tentar mexer novamente no arquivo de conexão e realmente o erro tava no ConnectionCreator.php mesmo

mexi aqui

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

no caminho do sqlite estava com um /.. a menos e este arquivo ConnectionCreator.php está 4 diretórios "acima (ou abaixo?)" do sqlite que tá na pasta raiz

agora executei o criar-turma.php e depois listar-alunos.php e apareceram os novos alunos na lista

Obrigada pela ajuda!!! :)