Neste artigo iremos aprender a customizar nossos modelos, o zend framework oferece uma hierarquia de classes para abstrair cada nível do banco de dados, desde uma tabela até um resgistro dessa tabela, dando flexibilidade aos modelos.
Camadas de abstração para banco de dados no zend framework
Confira abaixo as classes que o zend framework oferece para abstrair o banco de dados.
- Zend_Db_Table – Está classe representa uma tabela do nosso banco de dados e oferece métodos para funcionalidades básicas de manipulação, inserir, editar, remover registros, etc.
- Zend_Db_Table_Row – Quando trabalhamos com modelos no zend framework, cada registro de uma tabela é representado por um objeto e a classe responsável por isso é a classe Zend_Db_Table_Row.
- Zend_Db_Table_Rowset – Está classe representa um conjunto de registros, ou seja, um conjunto de objetos do tipo Zend_Db_Table_Row.
Então para mastigar de vez, a classe Zend_Db_Table representa uma tabela, Zend_Db_Table_Row representa um registro da tabela e Zend_Db_Table_Rowset representa um conjunto de registros de uma tabela.
Resgatando um objeto do tipo Zend_Db_Table_Row
A classe Zend_Db_Table oferece o método fetchRow(), que retorna um objeto do tipo Zend_Db_Table_Row representando um registro da tabela. O zend framework permite a criação de classes customizadas para representar registros de determinadas tabelas, para isso, precisamos criar uma classe extendendo Zend_Db_Table_Row_Abstract e configurar o modelo informando qual classe representará os seus registros, veremos mais detalhes dessa configuração no final do artigo.
Resgatando um objeto do tipo Zend_Db_Table_Rowset
A classe Zend_Db_Table oferece os métodos find() e fetchAll(), ambos os métodos retornam um objeto do tipo Zend_Db_Table_Rowset representando um conjunto de registros, o zend framework também permite a criação de classes customizadas para representar esses conjuntos, para isso, precisamos criar uma classe extendendo Zend_Db_Table_Rowset_Abstract e configurar o modelo informando qual classe representará os seus conjuntos de registros.
Vale lembrar que ao iterar um objeto do tipo Zend_Db_Table_Rowset, cada item da iteração será um objeto Zend_Db_Table_Row.
Normalmente o método find() é utilizado para resgatar um registro pelo seu ID, mas o método aceita varios ID´s, motivo pelo qual retorna um objeto do tipo Zend_Db_Table_Rowset e não Zend_Db_Table_Row, para transformar o resultado obtido pelo método find() para um objeto Zend_Db_Table_Row, utilizamos o método current(), utilizado para retornar o item atual.
Projeto usando modelos customizados
Agora que vimos um pouco sobre as classes responsáveis pela customização dos modelos, vamos criar um projeto para trabalhar, baseado na estrutura apresentada no tópico Preparando o ambiente para desenvolvimento com Zend Framework, crie um projeto com nome de example-custom-models.
No exemplo que será visto agora, iremos utilizar o banco apresentado no artigo Mapeando relacionamentos nos modelos, para criar nossos modelos customizados, confira o diagrama do nosso banco de dados:
Visualize ou efetue o download do script sql, no script além dos comandos de criação das tabelas, contém comandos para inserir valores nas tabelas para que o exemplo no final do artigo funcione corretamente.
Acesse o phpmyadmin, crie o banco “zf-order” e execute o script sql acima para criar e preencher as tabelas do banco. Após criar o banco edite o arquivo application.ini com as informações do banco de dados, caso tenha dúvida, visualize o artigo Entendendo modelos no zend framework.
Criando modelos e seus métodos
Com o banco devidamente criado, crie os arquivos das abas abaixo na pasta “application/models”.
No modelo User, realizamos a configuração e o mapeamento do modelo.
No modelo Product, realizamos a configuração e o mapeamento do modelo.
No modelo Order, além de realizar a configuração e o mapeamento do modelo, informamos ao modelo Order qual será sua classe Row através do atributo $_rowClass, ou seja, informamos qual classe será responsável por representar um registro do modelo Order.
No modelo OrderItem, além de realizar a configuração e o mapeamento do modelo, nós informamos ao modelo OrderItem qual será sua classe Rowset através do atributo $_rowsetClass, ou seja, informamos qual classe será responsável por representar um conjunto de registros do modelo OrderItem, também criamos um método, findByOrder($order), que lista todos os produtos e quantidade de um determinado pedido, que será passado por parâmetro.
Criando as classes Order Row e OrderItem Rowset
Para manter nosso projeto organizado, crie duas pastas, Row e Rowset, dentro da pasta “application/models”, agora crie um arquivo chamado Order.php na pasta Row e outro arquivo chamado OrderItem.php na pasta Rowset, confira o conteúdo desses arquivos a seguir.
Row/Order.php
Como vimos anteriormente, para criar uma classe Row personalizada, precisamos extender a classe Zend_Db_Table_Row_Abstract, a finalidade dessa classe row é dar flexibilidade ao manipular um registro do modelo Order, adicionamos dois métodos, getUser(), que retorna o registro do usuário que realizou o pedido e getItens(), que retorna os itens do pedido.
Rowset/OrderItem.php
Para criar uma classe Rowset personalizada precisamos extender a classe Zend_Db_Table_Rowset_Abstract, a finalidade dessa classe rowset é manipular um conjunto de registros do modelo OrderItem, nesse caso criamos o método getAsArray(), que personaliza os resultados em um array, adicionando apenas as colunas name e amount.
Estrutura da pasta models, após a criação das classes Row e Rowset:
Trabalhando com os modelos customizados
Com os nossos modelos criados, nosso Row e Rowset configurado, vamos trabalhar com os modelos customizados, para isso vamos utilizar o IndexController.php e sua view, index.phtml.
IndexController.php
index.phtml
Estrutura final do nosso projeto:
Resultado
Ao executar nossa aplicação iremos obter o seguinte resultado:
Confira o código-fonte do exemplo no GitHub.