Archive for March, 2008

Relacionamento entre tabelas com Zend Framework

Tuesday, March 25th, 2008

zf logo

O Zend Framework possui uma camada de modelo, composta por algumas classes como Zend_Db, Zend_Db_Table, Zend_Db_Table_Rowset, entre outras, e é muito simples criar uma classe que representa uma determinada tabela, basta herdar da classe Zend_Db_Table_Abstract que você terá todos os métodos principais de acesso à dados, como insert, update, etc.

Porém as tabelas possuem relacionamentos e uma entidade em uma tabela pode ser ligada a uma ou mais entidades em outra tabela utilizando integridade referencial, e o Zend Framework permite que você faça isso tudo no nível de objeto através de métodos específicos da classe Zend_Db_Table_Row.

Para demonstrar isso, vou usar como exemplo uma relação bem simples. Supondo que existam as seguintes tabelas:

UF
id - INT - PRIMARY KEY
nome - Varchar(100)

CIDADE
id - INT - PRIMARY KEY
nome - Varchar(100)
uf_id - INT - FOREIGN KEY

Se criarmos duas classes no Zend Framework para representar essas tabelas, nós faríamos o seguinte:

class UF extends Zend_Db_Table_Abstract
{
protected $_name = "uf";
}
class Cidade extends Zend_Db_Table_Abstract
{
protected $_name = "cidade";
}

Com essas duas classes nós já possuímos os métodos necessários para inserir, alterar, excluir e recuperar os dados delas, porém, de maneira independente. Para recuperarmos todas as cidades de um determinado estado por exemplo, nós poderíamos fazer o seguinte:

Primeiro, uma pequena alteração nas classes:

class UF extends Zend_Db_Table_Abstract
{
protected $_name = "uf";
protected $_dependentTables = array('Cidade');
}

class Cidade extends Zend_Db_Table_Abstract
{
protected $_name = "cidade";
protected $_referenceMap = array(
'UF' => array(
'columns' => 'uf_id',
'refTableClass' => 'UF',
'refColumns' => 'id'
)
);
}

Calma, já vou explicar:

Na propriedade da classe UF $_dependantTables, eu defino quais tabelas/classes que são dependentes da tabela UF, passando simplesmente o nome da classe como um elemento de um array. Pode-se passar quantos nomes de tabelas/classes forem necessárias, desde que cada um seja um elemento distinto.

Na propriedade da classe Cidade $_referenceMap, nós fazemos o mapeamento entre as duas classes, onde a coluna uf_id da tabela Cidade é uma referência ao campo id da tabela UF. Simples demais!

Vamos testar?

Eu vou mostrar duas maneiras diferentes para retornar todas as cidades de uma determinada UF, a primeira segue abaixo:

PS: Eu vou criar um IndexController para executar este exemplo.

include_once 'UF.php';
include_once 'Cidade.php';

class IndexController extends Base_Controller_Action
{
public function indexAction()
{
// Cria instância da classe UF
$tabelaUF = new UF();

// Pesquisa pelo UF 1 (1 é o ID do UF na tabela UF)
$ufRows = $tabelaUF->find(1);

// Retorna o Zend_Db_Table
$uf = $ufRows->current();

// Pesquisa pelas cidades referentes ao UF consultado acima
$cidadesPorUF = $uf->findDependentRowset(’Cidade’);

// Mostra resultado
echo ‘<pre>’;
print_r($cidadesPorUF);
echo ‘</pre>’;

}
}

Simples não?

O Outro exemplo terá o mesmo resultado porém a maneira como consultaremos as cidades por dada UF será um pouco diferente.
Se você está acostumado com PHP 5, você já conhece os chamados ‘métodos mágicos’ como __call(), __set(), __get() certo? pois então, agora nós vamos usar um método mágico chamado FindCidadeByUF() só que esse método não existe em nossa classe, então de onde que ele veio? O Zend Framework possui um mecanismo que nos permite consultar tabelas dependentes utilizando métodos mágicos no seguinte formato: Find<Tabela>By<Tabela>, então ele dinamicamente saberá onde consultar os dados, basta substituirmos a primeira <Tabela> pelo nome da classe Cidade e a segunda tabela pela classe UF que ele se encarrega do resto.

Veja o exemplo:

include_once 'UF.php';
include_once 'Cidade.php';

class IndexController extends Base_Controller_Action
{
public function indexAction()
{
$tabelaUF = new UF();
$ufRows = $tabelaUF->find(1);
$uf = $ufRows->current();

$cidadesPorUF = $uf->findCidadeByUF();

echo ‘<pre>’;
print_r($cidadesPorUF);

}
}

Interessante não é? Veja o resultado:

resultado exemplo zf

Considerações finais

Espero ter conseguido demonstrar este mecanismo interessante do Zend Framework. Espero que da mesma forma com que ele tem auxiliado o trabalho ele também auxilie o seu.

O que que você achou? Deixe aqui seu comentário.

A propósito, nos últimos dias alguns colegas me perguntaram bastante coisa sobre o Zend Framework, muitos queria fazer um hello world para entender o padrão dele, outros queriam algo mais avançado, então eu pensei: Porque não escrever uma série de tutoriais no meu blog? Isso pode ser útil para muito mais pessoas. Então gostaria de sua opinião. Deixe seu comentário.

Eu estou pensando em fazer uma série de artigos simples e diretos ao assunto sobre Zend Framework, abordando desde o básico até o mais avançado. Então, espero começar na próxima semana.

abraço.

Lehitraot, Guterman

Sunday, March 23rd, 2008

Marcos Guterman é editor do estadao.com.br e ele tinha um blog no portal do estadão que era um dos mais movimentados. O blog dele normalmente tratava de questões política internacional e história normalmente relacionadas ao oriente-médio, porém, sem pender para lado algum. Em muitos casos ele trazia informações que nada tinham a ver com os conflitos que são comuns naquela região.

Um blog tão movimentado atrai espécimes indesejáveis e isso não foi diferente no blog dele. Era comum pessoas escondidas sob a anonimidade que a internet proporciona postarem comentários no blog dele o ofendendo com textos anti-semitas somente porque ele é judeu. Foram raros os casos em que alguém discutia os posts dele com argumentos plausíveis, eu vi uma vez, uma pessoa de origem muçulmana, discutindo com ele a respeito do que estava escrito, de maneira civilizada, sem problemas, mas a grande maioria pregava o fim dos judeus e do estado de Israel. Um anti-semitismo ridículo, porém eficaz.

Entre outros motivos para fechar o blog, ele disse o seguinte:

Infelizmente, por causa do meu sobrenome e da minha religião, muitas
pessoas apareceram por aqui para ofender os judeus, mentir sobre o
Holocausto e desejar o fim do Estado de Israel. Agüentei o quanto pude,
mas, em nome da memória de meus avós, decidi que já tive o bastante.

O melhor é ele se resguardar mesmo. Seu blog era um referencial, porém, acredito que a maioria das pessoas que liam seus posts entenderão.

Então, Lehitraot Guterman.

FLISOL 20008 - Mudança de planos

Thursday, March 20th, 2008

Já estava tudo definido em relação à minha participação no FLISOL-DF desse ano, porém por alguns imprevistos profissionais eu não poderei participar mais e tive de cancelar a minha participação.

Eu busquei entre os membros do PHPDF alguém para me substituir e se der tudo certo minha palestra será substituída por outra de PHP, então o PHPDF continuará sendo representado no evento.

Eu participei das edições 2006 e 2007 do FLISOL-DF e sempre achei bem legal participar, infelizmente esse ano para minha tristeza (acho que só minha mesmo :D) não será possível.

A gente se vê em outro evento (quem sabe no próximo PHPDF Roadshow).