Desenvolvendo no padrão MVC com Zend Framework

Posted on April 26th, 2007 in Framework, Php, Tecnologia | 1 Comment »

Quando se fala de desenvolvimento no padrão MVC com o PHP a primeira palavra que se vém a mente é framework. E pesquisando sobre essa palavra, iremos encontrar uma vasta lista de ambientes. Desta lista, já testei o Symfony, Cake, CodeIgniter e QCodo. Até agora, nenhum satisfez minhas necessidades completamente, talvez por serem fechados ou pesados demais, esta é minha a opinião. Mas isso até eu começar a estudar o Zend framework, que não é exatamente um framework, mas sim um conjunto de componentes prontos que oferecem funcionalidades para se montar um framework de desenvolvimento no padrão MVC, como também utilizar os mesmos componentes em aplicações que não usem necessariamente este padrão.

A proposta dele é excelente, o que possibilita digamos, da criação do seu próprio framework, com a estrutura (scaffold) criada a sua maneira. Existem excelentes artigos já em português falando sobre ele, além de um manual completo de utilização. Por isso não vou me estender falando sobre ele.

Uma das dificuldades de alguns desenvolvedores que começaram a utilizá-lo e alvo de constantes questionamentos é a falta do componente que implementa a camada Model. Apesar de já possuir uma bom componente para abstrair o banco de dados e manipular seus dados sem a necessidade de muitos comandos SQL, a camada model ainda faz uma falta, mesmo não sendo um problema grave, já que é possível utilizar qualquer biblioteca que faça o mapeamento objeto relacional como o Lumine, Propel, Doctrine entre outros. Mas ao utilizar qualquer uma dessas bibliotecas, o componente Zend_Db acaba perdendo um pouco a sua utilidade.

Por isso, resolvi escrever e tentar submeter este componente ao core do ZendFramework. Até o momento tenho duas classes escritas parcialmente em testes: Zend_Model e Zend_Model_Import. A primeira classe mapeia o diretório onde estão as entidades e as carrega a medida que forem sendo necessárias, usando um arquivo XML gerado que armazena dados de conexão ao banco ou simplesmente usando uma conexão já feita anteriormente. A segunda classe lista as tabelas do banco e gera as classes das entidades do modelo automaticamente ou importa a partir de um xml contendo todo o esquema do banco.

Nos próximos posts vou mostrar mais ou menos como estou implementando essa camada e coletar sugestões para futuras alterações, antes de submetê-la.

Até a próxima.

Alterando o Lumine Config para diferentes servidores

Posted on March 16th, 2007 in Php | 2 Comments »

Atualmente venho utilizando o Lumine, um framework usado para mapeamento objeto relacional para banco de dados, que foi desenvolvido pelo Hugo, meu amigo e ex-sócio na administração do MXSTUDIO. Não me aprofundarei falando sobre as características do framework, deixando para um próximo post mais elaborado que certamente valerá a pena.

Em minha opinião, o Lumine está entre as melhores ferramentas para gerar e trabalhar um camada de persistência usando o mapeamento objeto relacional de um banco, graças a sua simplicidade de implementação e velocidade na execução dos comandos de inserção e seleção de dados.

Como disse anteriormente, em outro post relatarei em detalhes a ferramenta, que segundo o autor, ainda necessita de uma documentação mais completa que ainda não pôde ser feita devido à falta de tempo do mesmo. Desta forma, quem tiver interesse em contribuir, fique a vontade.

No Lumine existe um arquivo de configuração que é utilizado para todas as operações entre a aplicação e o banco de dados, desde a conexão, carregamento das classes referentes aos objetos relacionais, engenharia reversa, criação deschemas, etc. Este arquivo pode ser gerado tanto em XML quanto em PHP. Particularmente, acredito que o formato PHP é mais interessante por ter as informações de configuração armazenadas em um array , impossibilitando desta forma que um usuário veja esses dados acessando o arquivo direto pela URL, caso o mesmo esteja visível na árvore de diretórios do site. Já comXML isso não acontece, a não ser que você configure os mime types permitidos para acesso externo, ou simplesmente altere a permissão do mesmo arquivo via FTP para que ele não seja lido pelo via browser.

Aqui vou falar apenas do arquivo PHP, uma vez que no XML o trabalho é manual mesmo, não há outra saída. No arquivo de configuração, há duas chaves importantes que são a base para o carregamento das classes de negócio:class-path e use-cache. Veja abaixo um exemplo deste arquivo:

$lumineConfig = array (
	’configuration’ => array (
		‘class-path’ => ‘C:\lumine’,
		‘host’ => ‘localhost’,
		‘database’ => ‘meudatabase’,
		‘dialect’ => ‘mysql’,
		‘port’ => ‘3306′,
		‘user’ => ‘usuario’,
		‘password’ => ‘*****’,
		‘package’ => ‘orm’,
		‘maps’ => ‘map’,
		‘use-cache’ => ‘C:\lumine\cache.txt’,
		‘remove_prefix’ => ”,
		‘acao’ => ‘Iniciar’,
		‘create-classes’ => ‘1′,
		‘create-maps’ => ‘1′,
		‘escape’ => ‘1′,
		‘empty-as-null’ => ‘1′,
		‘generate-accessors’ => ‘1′,
		‘fileDate’ => filemtime(__FILE__)
	),
	’maps’ => array (
	‘map.Pessoa’
	)
);

Repare que o valor do caminho do class-path é o padrão de diretório do Windows. Supondo que o seu servidor de produção seja Linux e que o servidor de testes seja Windows, então é provável que um erro no carregamento das classes aconteça em um dos sistemas por um não reconhecer a árvore de diretório do outro. A solução neste caso seria alterar então o caminho do diretório de forma que cada sistema leia o arquivo que contenha o diretório relativo ao seu sistema de diretório, ou seja, uma versão para o Windows e outro para o Linux. Mas isso não é muito saudável, uma vez que um erro de sincronização poderia fazer com que um arquivo sobrescrevesse o outro. Já passei por esta experiência e posso afirmar que alterar caminhos físicos de diretório manualmente é extremamente trabalhoso e chato.

Este arquivo de configuração pode ser gerado tanto manualmente quanto automaticamente pelo LumineReverse, uma classe utilizada para a construção das classes e mapeamentos xml do banco usando engenharia reversa. Neste processo, o Lumine gera o caminho para as classes, mapeamentos e o cache, de acordo com o sistema operacional em que ele estiver rodando. Por isso, é bom ficar atento a este detalhe.

Uma solução para não ter problemas quanto ao caminho correto, é usar a função dirname do php, que retorna o caminho completo do arquivo passado por parâmetro. Neste caso, o parâmetro é a constante global __FILE__, que indica o caminho do arquivo relativo aoscript que está executando o comando. Exemplo:

<?php
// Caminho original do arquivo: C:\aplicacao\lumine-config.php
echo dirname(__FILE__); // Retorna C:\aplicacao
?>

Mas atenção, isso só é válido se você tiver o lumine-config no mesmo diretório dos diretórios de mapeamento e pacote de classes. Exemplo da estrutura:

aplicacao
/mapeamentos
/pacote
lumine-config.php
cache.txt

Alterando então as diretivas use-cache e class-path para que ambas funcionem em qualquer servidor, com a necessidade apenas de alteração do usuário, host e senha do banco a qual o script irá se conectar, o arquivo ficará assim:

$lumineConfig = array (
	’configuration’ => array (
		‘class-path’ => dirname(__FILE__),
		‘host’ => ‘localhost’,
		‘database’ => ‘meudatabase’,
		‘dialect’ => ‘mysql’,
		‘port’ => ‘3306′,
		‘user’ => ‘usuario’,
		‘password’ => ‘*****’,
		‘package’ => ‘orm’,
		‘maps’ => ‘map’,
		‘use-cache’ => dirname(__FILE__) . ‘/cache.txt’,
		‘remove_prefix’ => ”,
		‘acao’ => ‘Iniciar’,
		‘create-classes’ => ‘1′,
		‘create-maps’ => ‘1′,
		‘escape’ => ‘1′,
		‘empty-as-null’ => ‘1′,
		‘generate-accessors’ => ‘1′,
		‘fileDate’ => filemtime(__FILE__)
	),
	’maps’ => array (
	‘map.Pessoa’
	)
);

Assim, o carregamento verificará o caminho para as classes e para o arquivo cache.txt, de acordo com o que retornar a função dirname, em tempo real, e com o sistema em que o script estiver rodando, eliminando a possibilidade de erros e leitura dos dados por estarem em caminhos diferentes.

Em um outro artigo, falarei sobre o Lumine e introduzirei alguns macetes para inserção e seleção de dados simples e complexos.