Lumine – um exemplo prático de uso

Nesse post eu falei sobre o Lumine, um framework em PHP para persistência de dados (nos moldes do Hibernate para o Java e o DB_DataObjects do PEAR).
Resolvi dar uma para em uns projetos e realmente experimentar em algo que eu precisava, e me dediquei a abandonar as querys SQL. E funcionou.
Vou, abaixo, mostrar como fazer para persistir os dados postados por um formulário numa tabela de uma base (no caso, MySQL).

Vamos supor que você tenha uma tabela no banco chamada messages com as seguintes colunas:

id – tinyint, chave-primária e autoincrement
name – varchar, 64
email – varchar, 64
msg – varchar, 512
publishDate – date

Como seguinte script, cria-se a tabela:

CREATE TABLE `messages` (
  `id` tinyint(4) NOT NULL auto_increment,
  `name` varchar(64) NOT NULL,
  `email` varchar(64) NOT NULL,
  `msg` varchar(512) NOT NULL,
  `parentId` tinyint(4) NOT NULL,
  `publishDate` date NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

O html que contém o formulário (no caso, um formulário em que um usuário posta o nome, e-mail e uma mensagem) é bem simples e já abordei essa técnica usando a biblioteca prototype (sinta-se livre pra usar qualquer outro framework, ou outra técnica; não influencia no resultado final) em outros posts(aqui e aqui):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Upload de mensagem</title>
<script src="http://www.prototypejs.org/assets/2008/1/25/prototype-1.6.0.2.js"></script>
<script type="text/javascript">
    function upload() {
        $("message").update("<img src=´loader.gif´> aguarde, enviando mensagem...");
        $("form_upload").request({
          onComplete: function(transport){
            if(transport.responseText=="")
                $("form_upload").reset();
                $("message").update("Sua mensagem foi enviada com sucesso... obrigado!");
            }
               
        });
        return false;
    }
</script>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="box">
<h1>Envio de mensagem</h1>
<form action="saveMsg.php" method="post" enctype="application/x-www-form-urlencoded" id="form_upload" onsubmit="return upload();">
    <label for="name">nome:</label><input type="text" id="name" name="name" class="field" /><br /><br />
    <label for="email">e-mail:</label><input type="text" id="email" name="email" class="field" /><br /><br />
    <label for="msg">mensagem:</label><textarea id="msg" name="msg"></textarea><br />
    <input type="submit" value="enviar" class="submitButton" />
    <span id="message"></span>
</form>
<div id="msgs_area"></div>
</div>
</body>
</html>

Agora, o passo mais importante: modelar (exemplo: http://www.hufersil.com.br/documentacao/instanciando) uma classe seguindo a estrutura da sua tabela. No arquivo Message.php eu criei a classe, extendendo a classe do Lumine, mapeando os atributos relativos à tabela.

<?php
class Message extends Lumine_Base{
    protected $_tablename = ´messages´;
    protected $_package   = ´entidades´;
    protected function _initialize() {
        $this->_addField(´id´, ´id´, ´tinyint´, 4, array(´primary´ => true, ´notnull´ => true, ´autoincrement´ => true));
        $this->_addField(´name´, ´name´, ´varchar´, 64, array());
        $this->_addField(´email´, ´email´, ´varchar´, 64, array());
        $this->_addField(´publishDate´, ´publishDate´, ´date´,null , array());
        $this->_addField(´msg´, ´msg´, ´varchar´, 512, array());
        $this->_addField(´parentId´, ´parentId´, ´tinyint´, 4, array(´primary´ => false, ´notnull´ => true, ´autoincrement´ => false));
    }
}
?>

Então, o passo final é criar o arquivo que recebe o post do formulário (no caso, saveMsg.php).
Nesse arquivo, o que fazemos: chamamos a classe Lumine.php (que vem no pacote de instalação do Lumine), configuramos a aplicação (http://www.hufersil.com.br/documentacao/lumine_conf), depois atribuímos os valores recebidos por POST a cada parâmetro enviado pelo formulário (e pegamos a dataa atual para salvar no banco) e, por final, chamamos o método insert() que faz salvar os dados na tabela do banco.
Segue o código:

<?php
require "../lumine/Lumine.php";
require "lumine_config.php";
$cfg = new Lumine_Configuration( $lumineConfig );
require "Message.php";
//cria classe Message
$msg = new Message;
//decodifica os pareâmetros enviados, para evitar problemas com acentuaçãao
foreach ($_POST as $key => $valor ){
   $_POST[$key] = utf8_decode($valor);
}
$msg->name = $_POST["name"];
$msg->email = $_POST["email"];
$msg->msg = $_POST["msg"];
$msg->publishDate=date(DATE_RFC822);
$msg->insert();
?>

Passei batido por alguns detalhes aqui relativos à configuração, mas a documentação oficial é muito boa – e o próprio ato de configurar é algo bem simples para quem está na área de desenvolvimento.
E, olhando assim por cima, parece que há muito trabalho para configurar tudo isso para fazer apenas uma inserção no banco; mas, imaginem só configurar uma vez só, e depois acabar com todas querys de inserts, updates, selects, etc… Muito bom, aprovado!

 

Site oficial: http://www.hufersil.com.br/documentacao/apresentacao

Lumine – mapeamento de banco de dados para PHP

Quando entrei no meu atual emprego, quase 4 anos atrás, uma cosia que eu não conhecia mesmo era esse lance de frameworks.
Talvez pela mistura de ser novato em programação web (conhecia bem html/css e um pouco de php) e ter trabalhado com programação c/c++, onde os programadores prezam muito o fato de se conhecer como as coisas funcionam – e não só fazer funcionar.

No fundo, eu concordo: não acho o ideal já partir de cara para o uso de frameworks, sem nem saber como as coisas são feitas na unha. Até porque, quando aparece algum problema no desenvolvimento, na maior parte das vezes temos que mudar algo no framework, ou fazer um work-around indo lá no meio do código – ou seja, fazer o trabalho sujo de catar milho e escrever código.

Um dos frameworks que mais me chamou atenção foi o Hibernate. É um framework para aplicações java, para persistêcnia de dados. Basicamente, você persiste objetos (sim, objetos, aqueles, do conceito da Orientação a Objetos) em bancos de dados sem ter que se preocupar em como isso vai funcionar; ao invés de ter que ficar escrevendo querys SQL de consulta, inserção, deleção, etc… você chama apenas um método específico que os objetos herdam, e o framework faz todo o trabalho.
Qual a vantagem? Bancos de dados SQL possuem uma estrutura totalmente diferente da forma como os dados existem na orientação a objetos. Fazer código para manipular os dados é custoso – tanto em termos de tempo quanto de trabalho. Quando o framework se propõe a fazer isso, o ganho de produtividade é gigantesco. Sem falar que, com isso, mudar de um banco de dados para o outro é bem mais simples, pois normalmente frameworks desse tipo possuem tal suporte.

Depois de ter conhecido esse framework, fiquei um tempo pensando se não tinha nada parecido em PHP (que é a linguagem server-side para web que mais conheço). Foi quando me deparei com o Lumine. Ele surgiu depois que um programador PHP conheceu também o Hibernate e sentiu necessidade de fazer o mesmo para PHP.
*não conheço o autor desse framework, mas já deixo aqui meus parabéns pra ele
A configuração dele é muito fácil: você escolhe qual banco de dados vai usar (por enquanto pode usar MySQL e PostGree) e define as strings de conexão (login, senha, etc…).
Depois, faz o mapeamento das classes com relação às tabelas do banco. Ou seja, você específica que uma classe (por exemplo Pessoa) estará relacionada a uma tabela do bando (chamada tbl_pessoa) e que os atributos (por exemplo nome, idade, sexo) estarão relacionados a colunas específicas da tabela.
Feito isso, você pode usar os métodos específicos para manipulação dos dados, como inserir uma nova Pessoa:

// recupera o arquivo que faz a configuração de lumine
// descrita anteriormente em "inicializando a configuração"
require_once ´configuracao.php´;
// Importa a classe pessoa
Util::Import(´entidades.Pessoa´);
// instancia a classe pessoa
$pessoa = new Pessoa;
// atribui propriedades
$pesso->nome = ´Hugo´;
$pessoa->idade = 23;
$pessoa->cpf = ´12345678912´;
// persiste o objeto no banco, usando insert
$pessoa->insert();

 

Ou recuperar do banco:

// instancia um novo objeto
$pessoa = new Pessoa;
// recupera o objeto com código 1 pela primeira chave primária da classe
$total = $pessoa->get( 1 );

 

Fica muito mais fácil pois você deixa de ter que misturar as querys SQL no meio do seu código PHP; o desacoplamento é muito maior, e a legibilidade é bem melhor: faz muito mais sentido você ver no código Pessoa->insert() do que toda aquela linguiçona SQL…
Minha sugestão? Quando tiver um tempo, baixe esse framework e experimente. Explore. Há uma curva de aprendizado, claro, e no começo a produtividade cairá um pouco. Mas, depois, a agilidade que ele te dá valerá a pena 🙂