Introdução à doutrina ORM e padrão de mapeador de dados em PHP

Introdução à doutrina ORM e padrão de mapeador de dados em PHP

Objetivo

Aprenda os conceitos básicos de doutrina ORM, implementando o padrão de mapeador de dados com PHP.

Requisitos

  • Compositor (gerenciador de pacotes PHP)
  • Uma configuração de lâmpada de trabalho
  • Compreendendo a programação básica orientada a objetos e PHP
  • Compreendendo os conceitos básicos de banco de dados

Convenções

  • # - requer que os comandos Linux sejam executados com privilégios de raiz também
    diretamente como usuário root ou por uso de sudo comando
  • $ - Requer que os comandos do Linux sejam executados como um usuário não privilegiado regular

Introdução

O padrão de mapeador de dados é um padrão arquitetônico por meio do qual é possível alcançar a separação entre uma camada de persistência de dados (neste caso, um banco de dados MySQL) e uma representação de dados na memória (neste caso, objetos PHP), para que as duas camadas possam ser separadas e completamente inconsciente um do outro, respeitando assim a separação de preocupações.

Neste tutorial, veremos como dar nossos primeiros passos com a doutrina, uma implementação do padrão de mapeador de dados que faz parte do Symfony estrutura PHP, mas também pode ser usada por conta própria.

A criação do banco de dados

Antes de qualquer outra coisa, devemos criar o banco de dados que usaremos para persistência de dados. Neste tutorial, representaremos um usuário e suas postagens em um blog:

Mariadb [(nenhum)]> Criar blog de banco de dados; Mariadb [(nenhum)]> conceda todos os privilégios no blog.* Para 'testuser'@'localhost' identificado por 'testpassword'; Mariadb [(nenhum)]> Privilégios de descarga; Mariadb [(nenhum)]> saída; 


Instale e inicialize a doutrina

O próximo passo em nossa jornada será a instalação da doutrina: usaremos compositor, o pacote PHP e gerente de dependência. Na raiz do nosso projeto, criamos o compositor.arquivo json, especificando doutrina/orm como uma dependência:

"requer": "doutrina/orm": "^2.6 " 
cópia de

Agora, para prosseguir com a instalação, enquanto estiver no mesmo diretório, abra um terminal e execute:

$ compositor install

O compositor instalará a doutrina e todas as suas dependências dentro do fornecedor diretório que ele criará. Depois que a doutrina é instalada, precisamos inicializá -la. Salve o código abaixo em um arquivo (para este tutorial, vamos chamá -lo de bootstrap.php):

 'blog'; 'usuário' => 'testUser', 'senha' => 'testPassword', 'host' => 'localhost', 'driver' => 'pdo_mysql']; // obtenha o entity gerenciador $ entity_manager = doutrina \ orm \ entityManager :: create ($ conexão_parameters, $ configuration); 
cópia de

Primeiro de tudo, exigimos na linha 2 o arquivo compositor automaticamente AUTOLOAD.php, que cuida de automaticamente as bibliotecas necessárias.

Ligando para o CreateanNoTationMetAdataconfiguration Método estático do Configurar Classe na linha 5, começamos a configurar a doutrina. Este método leva 5 argumentos, mas forneceremos apenas os dois primeiros, deixando o resto para seus padrões, já que não estamos interessados ​​neles no momento.



O primeiro argumento na linha 6 é uma variedade de caminhos onde as aulas de entidade podem ser encontradas em nosso projeto. Uma entidade é uma classe que representa uma linha no banco de dados (a Rapstreação na memória que mencionamos acima): Em nosso exemplo, usaremos duas entidades: autor e postagem.

O segundo argumento na linha 7 assume um valor booleano e define se estamos trabalhando no modo "dev" ou não. Isso define o comportamento da doutrina sobre objetos de proxy e armazenamento em cache: quando no modo “Dev”, os objetos de proxy serão regenerados em cada solicitação e o cache acontecerá na memória, porque se supõe que durante o desenvolvimento, as mudanças acontecem com muita frequência. Vamos defini -lo como verdadeiro por enquanto.

Depois disso, devemos especificar os parâmetros de conexão nas linhas 11-16, na forma de uma matriz associativa que contém, em ordem, o nome do banco de dados, o usuário do banco de dados, a senha do banco de dados, o host do banco de dados e o driver para acessar o banco de dados. É importante perceber que em um nível mais baixo, a doutrina usa PDO para interagir com o banco de dados e foi projetado para ser o banco de dados-agnóstico.

Finalmente, criamos uma instância do objeto EntityManager na linha 20, chamando o método de fábrica de "criar" da classe EntityManager, passando a matriz de informações de conexão que acabamos de definir como primeiro parâmetro e o Configuração objeto como o segundo. O objeto EntityManager nos dará acesso a todas as nossas entidades e nos tornará capazes de gerenciar facilmente sua persistência e ciclo de vida.

Criando nossas entidades

É hora de criar nossas entidades. Assim como afirmamos na configuração, vamos criar um diretório de 'entidades' na raiz do nosso projeto para armazenar nossas entidades. A primeira entidade que vamos definir é Autor:

cópia de

Definimos nossa primeira entidade muito simples. Nós costumavamos anotações para dar a doutrina as informações necessárias para lidar com isso. Primeiro na linha 5, usando, @Entidade Estamos dizendo à doutrina que a classe deve ser considerada uma entidade, que será persistida no autor Tabela de banco de dados. Nesse caso, usamos a anotação @Table (name = "autor") na linha 6 para especificar isso, no entanto, nessa situação, é redundante, e poderíamos ter omitido completamente: é opcional e, se não for usado, a entidade será persistido em uma mesa com o nome do não qualificado nome da classe.

Cada propriedade da classe corresponde a uma coluna na tabela e devemos fornecer informações sobre o tipo de dados da tabela. O $ id Propriedade, por exemplo, representa a chave primária da tabela: declaramos isso usando o @Eu ia Anotação na linha 11.

O valor do eu ia A coluna será gerada automaticamente, é por isso que usamos o @GeneratedValue Anotação na linha 12. Tem sentido apenas quando associado a @eu ia, E, ao usá -lo, é até possível especificar a estratégia de geração de adotar (se nenhum for especificado, ele não AUTO).

O tipo de dados usado para nossa chave primária será Smallint, que definimos através do @Column (type = "smallInt") Anotação na linha 13. As outras duas propriedades são $ primeiro_name e $ last_name, e são definidos com a mesma técnica. Eles são do tipo corda: ao usar o mysql, ele será traduzido para o Varchar Tipo de dados do banco de dados. Para uma referência completa sobre associações de tipo de dados, você pode consultar esta página.

Ao usar a doutrina, a visibilidade das propriedades de uma classe de entidade pode ser protegido ou privado mas não é público.



Ainda não definimos getters e setters para a classe. Não há necessidade de fazer isso manualmente, pois a doutrina pode fazer isso por nós, e veremos como em um momento, ainda temos outra entidade para definir, Publicar:

cópia de

Introduzimos dois novos tipos de dados. O primeiro é texto Na linha 23, que mapeará e converterá dados de string sem um comprimento máximo: ao usar o MySQL, ele será convertido para o LongText tipo de dados. O segundo é data hora Na linha 28, para o nosso $ data propriedade. Ele será traduzido para o mesmo tipo para MySQL e em um caso de PHP Data hora objeto.

Agora podemos gerar nossos getters e setters, mas antes de fazer isso, devemos criar o CLI-Config.php Script na raiz do nosso projeto: é necessário para usar a doutrina da linha de comando:

cópia de

Agora, abra um shell de terminal no diretório raiz do projeto e execute o seguinte comando linux:

$ php fornecedor/bin/doutrina ORM: gerar entidades .

O comando acima gerará getters e setters para as entidades encontradas e as colocará dentro do diretório especificado. Agora, se dermos uma olhada no Autor Entidade que podemos ver que Getters e Setters foram gerados:

eu ia;  /*** Defina o primeiro nome. * * @Param String $ FirstName * * @return autor */ public function setFirstName ($ FirstName) $ this-> primeiro_name = $ FirstName; retornar $ this;  /*** Obtenha o primeiro nome. * * @return string */ função pública getFirstName () return $ this-> primeiro_name;  /*** Defina o último nome. * * @Param String $ LASTNAME * * @RETURN AUTOR */ Public Function SetLastName ($ LastName) $ this-> last_name = $ lastName; retornar $ this;  /*** Obtenha o último nome. * * @return string */ função pública getLastName () return $ this-> last_name;  
cópia de

O mesmo aconteceu para o Publicar entidade:

eu ia;  /*** Defina o título. * * @param string $ title * * @return post */ função pública Settitle ($ title) $ this-> title = $ title; retornar $ this;  /*** Obtenha o título. * * @return string */ função pública gettitle () return $ this-> title;  /*** Defina o texto. * * @param string $ text * * @return post */ public function setText ($ text) $ this-> text = $ text; retornar $ this;  /*** Obtenha texto. * * @return string */ função pública getText () return $ this-> text;  /*** Definir data. * * @param \ dateTime $ date * * @return post */ função pública setDate ($ date) $ this-> date = $ date; retornar $ this;  /*** Obtenha a data. * * @return \ DateTime */ Public function getDate () return $ this-> date;  
cópia de

Definindo a relação entre as entidades

Para o nosso exemplo, queremos definir um bidirecional para muitos relacionamento entre nossas entidades, onde bidirecional significa que cada entidade mantém uma referência ao outro. O relacionamento entre um autor e suas postagens é muitos para um (um autor pode escrever muitas postagens e muitas postagens podem pertencer a um autor). Usando a doutrina, definir essa associação é muito simples:

cópia de

Adicionamos uma nova propriedade em cada entidade. Em autor é $ postagens na linha 16, e na entidade post, $ autor na linha 36. Que tipo de tipo de dados essas variáveis ​​manterão? O primeiro, $ postagens será um exemplo de doutrina Arraycoltion Objeto: é uma aula especial usada para gerenciar melhor a coleção de entidades.

O segundo, $ autor, em Publicar.php, será um exemplo da entidade do autor, representando o autor do post: como dito antes, cada entidade mantém uma referência ao outro.

Da mesma forma que fizemos pelas outras propriedades, definimos o relacionamento usando anotações. No nosso caso, como estamos lidando com uma relação bidirecional um para muitos, usamos o @Um para muitos anotação na linha 13, na entidade do autor, e @ManytoOne Na linha 32 no post.

Nos dois casos, com TargetEntity Definimos qual entidade a propriedade aponta para. Por exemplo, no caso do autor $ postagens Propriedade, a entidade -alvo é post. Como você pode ver, usamos respectivamente o inversedby e Mappedby anotações. Essas anotações são usadas para dizer a doutrina qual propriedade, no outro lado do relacionamento, refere -se ao objeto: inversedby deve ser usado no lado que possui o Chave estrangeira, (Nesse caso, a entidade post).

Como você pode ver, no autor, usamos Mappedby, especificando que no entidade -alvo Post, a propriedade correspondente é $ autor. Também introduzimos um novo parâmetro, cascata, configurando -o para "tudo". Isso significa que, ao persistir ou remover a entidade do banco de dados, todas as suas postagens também serão influenciadas: por exemplo, a exclusão de um usuário também causará a exclusão de todas as suas postagens. É o que definimos via Em excluir cascata no código SQL.

Vice -versa, na entidade post, que mantém a chave estrangeira no banco de dados, usamos inversedby, dizendo à doutrina que no autor da entidade -alvo, a propriedade que se refere ao objeto é Postagens. Nós também usamos o @Joincolumn anotação na linha 33, especificando as colunas envolvidas na junção do SQL, definindo a chave estrangeira como não é anulável (NÃO NULO).

Uma vez definido o relacionamento entre as duas entidades, devemos atualizar os métodos necessários para gerenciar as propriedades adicionadas. Mais uma vez, apenas corremos:

$ php fornecedor/bin/doutrina ORM: gerar entidades .


Gerar o esquema de banco de dados

Em nosso exemplo, temos dados suficientes para poder gerar nosso esquema de banco de dados. Novamente, a doutrina pode nos ajudar, gerá -la automaticamente com base em nossas anotações. Tudo o que precisamos fazer é executar o seguinte comando linux:

$ php fornecedor/bin/doutrina ORM: esquema-tool: atualização-force

Se tudo correr bem, as tabelas de banco de dados serão geradas, vamos verificar:

Mariadb [(nenhum)] Descreva o blog.autor; +------------+------------+------+-----+---------- -+ ----------------+ | Campo | Tipo | Nulo | Chave | Padrão | Extra | +------------+------------+------+-----+---------- -+ ----------------+ | id | Smallint (6) | Não | PRI | Nulo | Auto_increment | | primeiro_name | Varchar (255) | Não | | Nulo | | | Último nome | Varchar (255) | Não | | Nulo | | +------------+------------+------+-----+---------- -+ ----------------+ mariadb [(nenhum)] Descreva.publicar; +-----------+--------------+------+-----+--------- + ------------------+ | Campo | Tipo | Nulo | Chave | Padrão | Extra | +-----------+--------------+------+-----+--------- + ------------------+ | id | Smallint (6) | Não | PRI | Nulo | Auto_increment | | autor_id | Smallint (6) | Não | Mul | Nulo | | | título | Varchar (255) | Não | | Nulo | | | texto | longText | Não | | Nulo | | | data | DateTime | Não | | Nulo | | +-----------+--------------+------+-----+---------+----------------+ 
cópia de

Como esperado, as tabelas correspondentes à nossa entidade foram geradas e reflete as anotações que especificamos. O código SQL usado para gerá -los é respectivamente:

Mariadb [(nenhum)]> Show Create Table Blog.autor; Tabela: Autor Criar Tabela: Criar Tabela 'Autor' ('Id' SmallInt (6) Não NULL Auto_increntle, 'First_Name' Varchar (255) colar utf8_unicode_ci não null, 'last_name' varchar (255) colate utf8_unicode_ci não -nul 'ID')) MOTOR = Innodb Auto_increntry = 2 charset padrão = utf8 colate = utf8_unicode_ci mariadb [(nenhum)] Show Create Table Blog.publicar; Tabela: Post Create Tabela: Criar Tabela 'Post' ('ID' SmallInt (6) Não NULL AUTO_INCREMENT, 'AUTOR_ID' SmallInt (6) não NULL, 'Title' Varchar (255) Collate utf8_unicode_ci não null, 'texto' Longtext Collate utf8_unicode_ci não nulo, 'date' dateTime não nulo, chave primária ('id'), chave 'idx_5a8a6c8df675f31b' ('autor_id'), restrição 'fk_5a8a6c8df675f31b'), key ('autor_id') Mecanismo = innodb auto_increment = 2 charset padrão = utf8 colate = utf8_unicode_ci 
cópia de

Usando o gerente de entidade

Agora é hora de mostrar como usar o Gerente de entidade:

setFirstName ("John") -> setLastName ("Smith"); $ entity_manager-> persist ($ autor); // Crie um novo post $ post = (novas entidades \ post ()) -> Settitle ("Hello Wold") -> setText ("Este é um post de teste") -> setauthor ($ autor) -> setDate (novo Data hora()); // Adicione a postagem para a lista das postagens do autor. Como usamos o cascade = "all", não precisamos persistir a postagem separadamente: ela será persistida ao persistir // o autor $ autor-> addpost ($ post); // Finalmente, descarte e execute a transação do banco de dados $ entity_manager-> flush (); 
cópia de

Executando esse código, criamos um autor e seu primeiro post, depois adicionamos a postagem à coleção de postagens do autor e, finalmente, os persistimos no banco de dados. Com o persistir() Método, estamos dizendo à doutrina para gerenciar a entidade, enquanto a transação real do banco de dados acontece apenas ao ligar rubor(). Se agora der uma olhada no autor e publicar Tabela, podemos ver que existe um novo registro em ambos:

Mariadb [(nenhum)]> Selecione * do blog.autor; +----+------------+-----------+| id | primeiro_name | Último nome | +----+------------+-----------+| 1 | John | Smith | +----+------------+-----------+mariadb [(nenhum)]> Selecione * do blog.publicar; +----+-----------+------------+--------------------- -+ ---------------------+ | id | autor_id | título | texto | data | +----+-----------+------------+--------------------- -+ ---------------------+ | 1 | 1 | Olá Wold | Este é um post de teste | 2018-04-17 08:37:44 | +----+-----------+------------+---------------------+---------------------+ 
cópia de

Também podemos usar o Entity Manager para recuperar uma entidade existente, por exemplo:

// Recuperar o autor pelo seu sobrenome $ autor = $ entity_manager-> getRepository ('entidades \ autor')-> findOneby (['last_name' => 'smith']); 
cópia de

Conclusões

O objetivo deste tutorial foi apresentá -lo ao padrão de mapeador de dados no PHP usando a doutrina: vimos como configurar e obter um gerente de entidade, como definir duas entidades básicas e definir um relacionamento comum entre eles por meio de anotações.

Doutrina é uma biblioteca muito poderosa: você pode usar a documentação do projeto para começar a dominar, espero que este possa ser um ponto de partida mínimo.

Tutoriais do Linux relacionados:

  • Coisas para instalar no Ubuntu 20.04
  • Instalação do Ampache Raspberry Pi
  • Como criar uma pilha de lâmpadas à base de docker usando o docker em…
  • Como instalar a pilha de lâmpadas no Almalinux
  • Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
  • Uma introdução à automação, ferramentas e técnicas do Linux
  • Ubuntu 20.04 truques e coisas que você pode não saber
  • Mint 20: Melhor que o Ubuntu e o Microsoft Windows?
  • Manipulação de big data para diversão e lucro Parte 1
  • Ubuntu 20.04 WordPress com instalação do Apache