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

Allowed memory size of

Olá! Tudo beleza?

Recebi esse erro:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in D:\Programação\Cursos\PHP\PHP e PDO\src\Domain\Model\Student.php on line 64

Pesquise um pouco e encontrei que na maioria das vezes isso se dá por ter usado maior quantidade de memória do que se foi designado. Entretando, utilizei o código:

ini_set('memory_limit', '1024M')

E também tentei alterar o valor no arquivo php.ini

Mas mesmo assim, o erro persistiu. E ainda alterei o valor para até 6GB para testar.

Gostaria de entender o porquê deste erro e como solucioná-lo.

5 respostas

PdoStudentRepository..

<?php

namespace Alura\Pdo\Infrastructure\Repository;

use Alura\Pdo\Domain\Model\{Student, Phone};
use Alura\Pdo\Domain\Repository\StudentRepository;
use DateTimeImmutable;
use DateTimeInterface;
use PDOStatement;
use PDO;

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 //buscando alunos por data
    {
        $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();
        $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);

    }

    public function insert(Student $student): bool
    {
        $insertQuery = 'INSERT INTO students (name, birth_date) VALUES (:name, :birth_date);'; //aqui poderia ter colocado o ?
        $stmt = $this->connection->prepare($insertQuery);


        $sucess = $stmt->execute([ //uma nova forma de passar parâmetros, se fosse com '?', não precisaria informar os indices, assim com um array numérico
            ':name' => $student->name(),
            ':birth_date' => $student->birthDate()->format('Y-m-d'),
        ]);

        if ($sucess) {
            $student->defineId($this->connection->lastInsertId()); //o pdo oferece esse método
        }
        return $sucess;
    }

    public function update(Student $student): bool
    {
        $updateQuery = 'UPDATE students SET name = :name, birth_date = :birth_date WHERE id = :id;';
        $stmt = $this->connection->prepare($updateQuery);
        $stmt->bindValue(':name', $student->name());
        $stmt->bindValue(':birth_date', $student->birthDate()->format('Y-m-d'));
        $stmt->bindValue(':id', $student->id(), PDO::PARAM_INT);

        return $stmt->execute;
    }

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

    public function studentsWithPhones(): array
    {
        //Como trazer dados de duas tabelas ao mesmo tempo
        $sqlQuery = 'SELECT students.id, 
                            students.name, 
                            students.birth_date,
                            phones.id AS phone_id,
                            phones.area_code,
                            phones.number
                    FROM students
                    JOIN phones ON students.id = phones.student_id;';
        $stmt = $this->connection->query($sqlQuery);
        $result = $stmt->fetchAll();
        //precisamos mapear para cada aluno que tem mais de uma telefone, apenas um espaço
        $studentList = [];
        foreach($result as $row) {
            if (!array_key_exists($row['id'], $studentList)) {
                $studentList[$row['id']] = new Student(
                    $row['id'],
                    $row['name'],
                    new \DateTimeImmutable($row['birth_date'])
                );
            }
            $phone = new Phone($row['phone_id'], $row['area_code'], $row['number']);
            $studentList[$row['id']]->addPhone($phone);
        }

        return $studentList;
    }
}

alunos-com-telefone

<?php   

use Alura\Pdo\Infrastructure\Persistence\ConnectionCreator;
use Alura\Pdo\Infrastructure\Repository\PdoStudentRepository;

require_once 'vendor/autoload.php';

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

$studentList = $repository->studentsWithPhones();

echo $studentList[1]->phones()[0]->formattedPhone;

var_dump($studentList);

class Student

<?php

namespace Alura\Pdo\Domain\Model;

//ini_set('memory_limit', '4024M'); // or you could use 1G

class Student
{
    private ?int $id;
    private string $name;
    private \DateTimeInterface $birthDate;
    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;
    }

    public function phones(): array
    {
        return $this->phones();
    }
}

A linha de erro, é a linha do Return..

    public function phones(): array
    {
        return $this->phones(); //linha de erro
    }
solução!

Tropa, não retornem a função dentro da pópria função kkkkkkkkkkkkk

return $this->phones(); ~

return $this->phones;

Falta de atenção. Depois de revisar o código várias vezes, verifiquei que o erro era de sintaxe(e simples ainda).