Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
11
respostas

erro ao inserir aluno e telefones no BD

Bom dia, estou com dificuldade na hora de inserir um aluno ao banco de dados, ele está retornando o seguinte erro:

c:\curso php\doctrine>php commands\criar-aluno.php "Marcos Silva" "937612857" "77981442272" "991091311"
PHP Fatal error:  A function with return type must return a value in C:\curso php\doctrine\src\Entity\Telefone.php on line 45

Fatal error: A function with return type must return a value in C:\curso php\doctrine\src\Entity\Telefone.php on line 45
``

o meu criar-aluno.php

<?php

use Alura\Doctrine\Entity\Aluno;
use Alura\Doctrine\Entity\Telefone;
use Alura\Doctrine\Helper\EntityManagerFactory;

require_once __DIR__ . '/../vendor/autoload.php';

$entityManagerFactory = new EntityManagerFactory();
$entityManager = $entityManagerFactory->getEntityManager();
$aluno = new Aluno();
$aluno->setNome($argv[1]);

for ($i = 2; $i < $argc; $i++){
    $numeroTelefone = $argv[$i];
    $telefone = new Telefone();
    $telefone->setNumero($numeroTelefone);
    $entityManager->presist($telefone);
    $aluno->addTelefone($telefone);
}

$entityManager->persist($aluno);
$entityManager->flush();

o aluno.php

<?php

namespace Alura\Doctrine\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use doctrine\Common\Colections\Collenction;

/**
 * @Entity
 */
class Aluno
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    private $id;
    /**
     * @Column(type="string")
     */
    private $nome;
    /**
     * @OneToMany(targetEntity="Telefone", mappedBy="aluno")
     */

    private $telefones;

    public function __construct()
    {
        $this->telefones = new arrayCollection();
    }

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

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

    public function setNome(string $nome): self
    {
        $this->nome = $nome;
        return $this;
    }

    public function addTelefone(Telefone $telefone){
        $this->telefones->add($telefone);
        $telefone->setAluno($this);
        return $this;

    }
    public function getTelefones(): Collection{
        return $this->telefones;
    }
}

e o telefone.php

<?php
namespace alura\Doctrine\Entity;

/**
 * @Entity
 */
class Telefone {
    /**
     * @Id
     *@GeratedValue
     *@Column(type="integer")
     */

    private $id;
    /**
     * @Column (type="string")
     */
    private $numero;

    /**
     * @ManyToOne (targetEntity="Aluno")
     */
    private $aluno;


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


    public function setId(int $id): self
    {
        $this->id = $id;
    }

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

    public function setNumero(string $numero): self
    {
        $this->numero = $numero;
        return;
    }


    public function getAluno(): Aluno
    {
        return $this->aluno;
    }


    public function setAluno(Aluno $aluno): self
    {
        $this->aluno = $aluno;
        return $this;
    }

}


?>

o que pode ser?

11 respostas

Olá Marcos, bom dia!

Tem alguns detalhes a serem corrigidos no código.

Primeiro na função setId de telefone, é informado um tipo de retorno mas nada é retornado:

public function setId(int $id): self
{
    $this->id = $id;
    // Falta o return 
    return $this;
}

Ainda em telefone, a função setNumero tem o return mas está faltando o $this:

public function setNumero(string $numero): self
{
    $this->numero = $numero;
    // Falta esse $this
    return $this;
}

Para finalizar acredito que em criar-aluno.php presist deveria ser persist

Verifica se com essas alterações o problema é resolvido.

obrigado pela ajuda. Esse persist já havia corrigido. Depois das alterações foi apresentado um novo erro:

PHP Fatal error:  Uncaught Doctrine\ORM\ORMException: Entity of type alura\Doctrine\Entity\Telefone is missing an assigned ID for field  'id'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly. in C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\ORMException.php:87
Stack trace:
#0 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\Id\AssignedGenerator.php(53): Doctrine\ORM\ORMException::entityMissingAssignedIdForField(Object(alura\Doctrine\Entity\Telefone), 'id')
#1 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(935): Doctrine\ORM\Id\AssignedGenerator->generate(Object(Doctrine\ORM\EntityManager), Object(alura\Doctrine\Entity\Telefone))
#2 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(1766): Doctrine\ORM\UnitOfWork->persistNew(Object(Doctrine\ORM\Mapping\ClassMetadata),  in C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\ORMException.php on line 87

Fatal error: Uncaught Doctrine\ORM\ORMException: Entity of type alura\Doctrine\Entity\Telefone is missing an assigned ID for field  'id'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly. in C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\ORMException.php:87
Stack trace:
#0 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\Id\AssignedGenerator.php(53): Doctrine\ORM\ORMException::entityMissingAssignedIdForField(Object(alura\Doctrine\Entity\Telefone), 'id')
#1 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(935): Doctrine\ORM\Id\AssignedGenerator->generate(Object(Doctrine\ORM\EntityManager), Object(alura\Doctrine\Entity\Telefone))
#2 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(1766): Doctrine\ORM\UnitOfWork->persistNew(Object(Doctrine\ORM\Mapping\ClassMetadata),  in C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\ORMException.php on line 87

Confere no início da classe telefone, no id está escrito @GeratedValue o correto seria @GeneratedValue

Após corrigir isso você vai ter que criar o banco novamente.

Fala, Marcos. Suas anotações no atributo id da classe Telefone estão erradas. Correto:

/**
 * @Id
 * @GeneratedValue
 * @Column(type="integer")
 */
private $id;

então, novo erro:

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Alura\Doctrine\Entity\Aluno::addTelefone() must be an instance of Alura\Dcoctrine\Entity\Telefone, instance of alura\Doctrine\Entity\Telefone given, called in C:\curso php\doctrine\commands\criar-aluno.php on line 19 and defined in C:\curso php\doctrine\src\Entity\Aluno.php:51
Stack trace:
#0 C:\curso php\doctrine\commands\criar-aluno.php(19): Alura\Doctrine\Entity\Aluno->addTelefone(Object(alura\Doctrine\Entity\Telefone))
#1 {main}
  thrown in C:\curso php\doctrine\src\Entity\Aluno.php on line 51

Fatal error: Uncaught TypeError: Argument 1 passed to Alura\Doctrine\Entity\Aluno::addTelefone() must be an instance of Alura\Dcoctrine\Entity\Telefone, instance of alura\Doctrine\Entity\Telefone given, called in C:\curso php\doctrine\commands\criar-aluno.php on line 19 and defined in C:\curso php\doctrine\src\Entity\Aluno.php:51
Stack trace:
#0 C:\curso php\doctrine\commands\criar-aluno.php(19): Alura\Doctrine\Entity\Aluno->addTelefone(Object(alura\Doctrine\Entity\Telefone))
#1 {main}
  thrown in C:\curso php\doctrine\src\Entity\Aluno.php on line 51

o codigo atualmente:

criar-aluno.php

<?php

use Alura\Doctrine\Entity\Aluno;
use Alura\Doctrine\Entity\Telefone;
use Alura\Doctrine\Helper\EntityManagerFactory;

require_once __DIR__ . '/../vendor/autoload.php';

$entityManagerFactory = new EntityManagerFactory();
$entityManager = $entityManagerFactory->getEntityManager();
$aluno = new Aluno();
$aluno->setNome($argv[1]);

for ($i = 2; $i < $argc; $i++){
    $numeroTelefone = $argv[$i];
    $telefone = new Telefone();
    $telefone->setNumero($numeroTelefone);
    $entityManager->persist($telefone);
    $aluno->addTelefone($telefone);
}

$entityManager->persist($aluno);
$entityManager->flush();

TElefone.php

<?php
namespace alura\Doctrine\Entity;

/**
 * @Entity
 */
class Telefone {
    /**
     * @Id
     *@GeneratedValue
     *@Column(type="integer")
     */

    private $id;
    /**
     * @Column (type="string")
     */
    private $numero;

    /**
     * @ManyToOne (targetEntity="Aluno")
     */
    private $aluno;


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


    public function setId(int $id): self
    {
        $this->id = $id;
        return $this;
    }

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

    public function setNumero(string $numero): self
    {
        $this->numero = $numero;
        return $this;
    }


    public function getAluno(): Aluno
    {
        return $this->aluno;
    }


    public function setAluno(Aluno $aluno): self
    {
        $this->aluno = $aluno;
        return $this;
    }

}


?>

aluno.php

<?php

namespace Alura\Doctrine\Entity;

use Alura\Dcoctrine\Entity\Telefone;
use Doctrine\Common\Collections\ArrayCollection;
use doctrine\Common\Collections\Collenction;

/**
 * @Entity
 */
class Aluno
{
    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    private $id;
    /**
     * @Column(type="string")
     */
    private $nome;
    /**
     * @OneToMany(targetEntity="Telefone", mappedBy="aluno")
     */

    private $telefones;

    public function __construct()
    {
        $this->telefones = new arrayCollection();
    }

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

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

    public function setNome(string $nome): self
    {
        $this->nome = $nome;
        return $this;
    }

    public function addTelefone(Telefone $telefone){
        $this->telefones->add($telefone);
        $telefone->setAluno($this);
        return $this;

    }
    public function getTelefones(): Collection{
        return $this->telefones;
    }
}

Ainda ficaram alguns erros de digitação.

Em aluno.php use Alura\Dcoctrine\Entity\Telefone; deveria ser use Alura\Doctrine\Entity\Telefone;

Ainda em aluno.php troca use doctrine\Common\Collections\Collenction; por use Doctrine\Common\Collections\Collection;

Recomendo também colocar o namespace de telefone.php com letra maiúscula para seguir o padrão:

namespace Alura\Doctrine\Entity;

caramba, muito erro de digitação.

pelo visto ainda resta mais algum hahhahah.

persiste o erro:

PHP Fatal error:  Uncaught PDOException: SQLSTATE[HY000]: General error: 1 no such table: Telefone in C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:61
Stack trace:
#0 C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php(61): PDO->prepare('INSERT INTO Tel...', Array)
#1 C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Statement.php(71): Doctrine\DBAL\Driver\PDOConnection->prepare('INSERT INTO Tel...')
#2 C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(858): Doctrine\DBAL\Statement->__construct('INSERT INTO Tel...', Object(Doctrine\DBAL\Connection))
#3 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php(271): Doctrine\DBAL\Connection->prepare('INSERT INTO Tel...')
#4 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(1073): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->executeInserts()
#5 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctr in C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\AbstractSQLiteDriver.php on line 43

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1 no such table: Telefone in C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:61
Stack trace:
#0 C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php(61): PDO->prepare('INSERT INTO Tel...', Array)
#1 C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Statement.php(71): Doctrine\DBAL\Driver\PDOConnection->prepare('INSERT INTO Tel...')
#2 C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(858): Doctrine\DBAL\Statement->__construct('INSERT INTO Tel...', Object(Doctrine\DBAL\Connection))
#3 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php(271): Doctrine\DBAL\Connection->prepare('INSERT INTO Tel...')
#4 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(1073): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->executeInserts()
#5 C:\curso php\doctrine\vendor\doctrine\orm\lib\Doctr in C:\curso php\doctrine\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\AbstractSQLiteDriver.php on line 43
solução!

Agora o problema já foi no lado do banco de dados, o erro tá dizendo que a tabela Telefone não existe.

Tenta recriar o banco. Na aula anterior a que você marcou nessa dúvida o instrutor mostra como limpar e criar o banco.

voltei na aula e refiz toda a parte de BD e deu certo, nem imagino o que havia feito de errado.... mas obrigado