Mostrando postagens com marcador mvc. Mostrar todas as postagens
Mostrando postagens com marcador mvc. Mostrar todas as postagens

terça-feira, 23 de dezembro de 2008

PHP: Uma introdução suave ao MVC (Parte 2)

Na primeira parte, vimos como desmontar um script PHP tradicional, separando a lógica de negócios da apresentação. Este foi o maior passo a ser feito: a partir de agora, nós vamos ajustar essa separação adicionando um terceiro cara na equação: o model. Senhoras e senhores, esta é a parte 2 de uma introdução suave ao MVC.

Parte 2: MVC completo

O MVC defende Modelo/Visão/Controle. É um padrão de projeto defendendo o uso de três camadas:

o model: o model é a camada de acesso aos dados, a única responsável por recolher dados requisitados (por exemplo, funções como getAllMembers() retornando um array PHP com todos os membros nele, ou addMember($name, $age, $city) para adicionar um membro novo no banco de dados).

o view: o view é a camada de apresentação onde é gerada a saída (o HTML final na página WEB exibindo os nomes dos membros com PHP usado como uma linguagem de template como em <li><?php echo $member['name']; ?></li>)

o controller: o controller destina-se a coordenar todo o processo analisando as requisições, executando o modelo correpondente para obter os dados (chamando getAllMembers() e colocando o array retornado na variável PHP $members), chama o view correspondente (include 'tpl/template.php') e preenche-o com dados ($members) e então envia a saída.

Aqui está um gráfico simples para entender melhor o padrão de projeto MVC:

A nova arquitetura dá mais flexibilidade na construção da aplicação:
  • a camada de acesso aos dados é terceirizada para o modelo, assim podemos trabalhar com uma abstração de dados: os dados armazenados podem estar em um banco de dados ou em arquivos XML, continuaremos acessando a lista de membros através da função getAllMembers().
  • a camada de apresentação é terceirizada para a view: se quisermos que a saída seja um feed RSS ao invés de uma página HTML, nós teremos apenas que mudar o view sem interferir na lógica ou no acesso aos dados.
Como você pode ver, o MVC é extremamente poderoso porque ele possibilita a divisão do script em partes naturalmente independentes, o que torna verdadeiro o velho sonho de reusabilidade: por exemplo, se quisermos que a saída seja tanto uma página HTML quanto um feed RSS exibindo todos os membros do community.com, podemos reutilizar o mesmo modelo e simplesmente criar dois templates diferentes (os arquivos 'tpl/template.php' e 'tpl/rss.php').

Agora vamos voltar para a implementação do padrão de projeto MVC. Chamando o controller diretamente através do endereço http://community.com/members.php, ele pode ser melhorado um pouco mais. Ao invés de chama-lo diretamente, vamos criar um ponto de entrada único chamado de router especificando que nós queremos mostrar os membros da página, este router analisará a requisição e entenderá que nós queremos mostrar a página membros, e executará o controller members.php. No CodeIgniter por exemplo, o ponto de entrada único é chamado de index.php e se quisermos chamar o controller members, teremos que digitar a seguinte URL: http://community.com/index.php/members. Nós também podemos imaginar uma URL menos sexy http://community.com/index.php?controller=members ou, ao contrário, se livrar do router através de algumas reescritas de URL e apenas chamar um elegante http://community.com/members.

Aqui está o que adicionamos ou clareamos nesta implementação MVC:
  • o router é o único ponto de entrada da aplicação que analisa cada requisição e carrega o controller correspondente.
  • o modelo interage com o banco de dados (mais uma vez, pode ser um conjunto de arquivos XML ou qualquer outra maneira de guardar dados, nós teríamos apenas que reescrever o modelo sem se preocupar com a saída final)
  • agora o view se torna o layout principal, que por sua vez, pode incluir sub-templates reutilizáveis (isto é diretamente inspirado no Ruby on Rails e tem sido reproduzido em muitos frameworks web)
Referências
Nemetral - Artigo Original (Parte 2)

sexta-feira, 12 de dezembro de 2008

PHP: Uma introdução suave ao MVC (Parte 1)

Boa noite. Encontrei no site NEMETRAL uma explicação prática sobre o padrão de projeto MVC em PHP. Depois de pedir as devidas permissões para o dono do conteúdo, traduzi o mesmo e aqui está a primeira parte dele. Enjoy! :)

Uma introdução Suave ao MVC

O MVC é certamente o padrão de projeto mais disseminado nos dias de hoje. Trazido de volta à moda pelo Ruby on Rails em 2004, ele foi traduzido e implementado em muitas linguagens e em mais de 100 frameworks web. Este tutorial ilustrado é focado em ajuda-lo a atravessar a lacuna entre um script PHP tradicional e uma implementação completa do MVC.

Parte 1: Desmontando uma página tradicional

Você se lembra do community.com? Aqui está algo que poderia ser um script server-side (executado do lado do servidor) usado para gerar uma página mostrando todos os membros de um site (assumindo um uso mediano do PHP):

<html>

<?php include 'inc/header.php'; ?>

<h1>Members of community.com:</h1>
<?php
// INITIALIZING THE DATABASE
$connection = mysql_connect('host', 'user', 'password');
mysql_select_db('database', $connection);
// PULLING OUT THE DATA
$data = mysql_query('SELECT name FROM members');
// DISPLAYING THE DATA
echo '<ul>';
$i = 1;
while ($member = mysql_fetch_array($data)) {
echo '<li>Member #' . $i . ': '. $member['name'] . '</li>';
$i++;
}
echo '</ul>';
?>

</html>

o arquivo inc/header.php fica da seguinte forma:

<head>
<title>Community.com rocks!</title>
</head>

Nota: Este é um HTML muito básico sem um DOCTYPE

Uma vez que os dados forem obtidos do banco de dados no meio de tags HTML, cada vez que você precisar mostrar o nome dos membros do site, você precisa reescrever o trecho PHP/SQL, o que torna mais difícil dar manutenção no seu código. Ainda assim, embora esta não seja uma forma impecável de escrever um código, esta não é uma maneira "burra" de escreve-lo: podemos ver o desmontamento do código através do uso do include, que faz possível começar a dividir o código em partes reusáveis (o header, por exemplo).

Aqui estão algumas coisas que poderíamos fazer para organizar o script:

  • Remover toda a lógica PHP (consultas ao banco de dados, formatação de dados, etc) da/entre as tags HTML e colar tudo acima da tag .
  • Usar variáveis PHP (preenchidas com os dados obtidos do banco de dados) para armazenar dados das/entre tags HTML.
  • Divisão do script: um para a lógica e o outro para a apresentação (baseado em variáveis PHP).

Aqui está um gráfico simples para entender melhor o processo:

O primeiro passo é o script original onde lógica de negócios (consulta ao banco de dados, obtendo os dados do banco de dados) é misturado com tags HTML. No segundo passo isolamos a lógica no início do script, mantendo as tags HTML abaixo do script e ligando os dois utilizando variáveis PHP. O terceiro passo é o passo final: nós simplesmente dividimos o script em duas partes (uma para a lógica e a outra para a apresentação em HTML). Aplicado ao nosso código, este seria o resultado no passo 3:

<?php
$connection = mysql_connect('host', 'user', 'password');
mysql_select_db('database', $connection);

$data = mysql_query('SELECT name FROM members');
$members = array();
while ($item = mysql_fetch_array($data)) {
$members[] = $item['name'];
}

include 'tpl/template.php';
?>

o arquivo tpl/template.php fica da seguinte forma:

<html>
<?php include 'tpl/header.php'; ?>
<h1>Members of community.com:</h1>
<ul>
<?php foreach ($members as $i => $member) : ?>

<li>Member #<?php echo $i + 1; ?>: <?php echo $member; ?></li>
<?php endforeach; ?>
</ul>
</html>

Nota: quando utilizamos o PHP como um template engine (isto é como estamos fazendo no segundo arquivo), é muito comum usar estruturas alternativas. Note também que mudei o diretório 'inc' para 'tpl', sendo este último encarregado de reunir todos os arquivos de template (o arquivo tpl/header, no passo 3 é o mesmo que o arquivo inc/header.php no passo 1).

Uma vez analisado, será exibida a seguinte saída HTML (supondo que existam apenas dois membros: Anna e Lisa):

<html>
<head>
<title>Community.com rocks!</title>
</head>
<h1>Members of community.com:</h1>

<ul>
<li>Member #1: Anna</li>
<li>Member #2: Lisa</li>
</ul>
</html>

Agora vamos nos afastar do script e dar uma olhada em toda a estrutura de requisições/respostas. Quando chamamos http://community.com/members.php, aqui está o que acontece:

  • o arquivo members.php obtém uma conexão com o banco de dados, obtém todos os nomes dos membros e preenche um array com eles (chamado de $members).

  • o arquivo members.php inclui o arquivo de template onde a variável $members é iterada e desta maneira é produzido o HTML final.

Isto pode ser chamado de arquitetura de View/Controller (Visão/Controle), onde o arquivo members.php é o controller e o arquivo tpl/template.php é o view:

Procedendo desta maneira, é possível separar a lógica da apresentação: primeiro executamos todas as consultas e então geramos a página HTML utilizando variáveis PHP.

Referências
Nemetral - Artigo Original (Parte 1)