Programação para WEB
Regis Pires Magalhães
regispiresmag@gmail.com
Implementando a
Arquitetura MVC em
PHP
MVC – Modelo, Visão, Controlador
 Model-view-controller (MVC) é um padrão de
arquitetura de software.
 Para que serve?
 Separar papéis para: reduzir a complexidade e
facilitar a manutenção, especialmente quando a
aplicação fica grande. Também facilita a divisão de
tarefas em uma equipe de trabalho.
 Tornar aplicações mais flexíveis e extensíveis.
 Permite inclusive a substituição da tecnologia de
uma camada sem afetar as demais.
MVC – Modelo, Visão, Controlador
 Como surgiu?
 Foi criado como padrão de projeto arquitetural
usado em interfaces de usuário na linguagem
Smalltalk.
Arquitetura MVC
Model
(Dados)
View
(apresentação
dos dados)
Controller
envia entrada de dados
exibe o modelo
Consulta ou
altera o modelo
define que visão será exibida
MVC – Modelo, Visão, Controlador
 Modelo
 Refere-se aos dados da aplicação.
 Pode usar mecanismos de armazenamento persistente
(bancos de dados) ou não.
 Visão
 Determina como o modelo vai ser mostrado ao usuário.
 Controlador
 Recebe interações do usuário e a partir delas, manipula o
modelo e determina a visão a ser usada.
 Pode alterar o modelo ou apenas consultá-lo para
posterior apresentação deste modelo a partir de uma
determinada visão.
 Em outras palavras, faz o “meio-de-campo” entre o modelo
e a visão.
Arquitetura MVC – Resumo
 Modelos – Dados;
 Visões – Como os dados são apresentados;
 Controladores – Recebe entrada de dados
do usuário. Manipula o modelo e determina a
visão para exibição do modelo.
Arquitetura MVC
Exemplo 1 – MVC Super Simples
 MVC bem simples para entendermos a
divisão.
 Modelo – pessoa.php
 Visão – pessoa_visao.php
 Controlador – pessoa_controlador.php
Modelo - pessoa_modelo.php
<?php
class Pessoa {
private $nome, $fone;
function __construct($nome, $fone) {
$this->nome = $nome;
$this->fone = $fone;
}
function getNome() {
return $this->nome;
}
function getFone() {
return $this->fone;
}
}
?>
Controlador - pessoa_controlador.php
<?php
require_once('pessoa_modelo.php');
class PessoaControlador {
function mostra() {
$pessoa = new Pessoa('Maria','(86)3323-1234');
require_once('pessoa_visao.php');
}
}
$pc = new PessoaControlador();
$pc->mostra();
?>
Visão - pessoa_visao.php
<html>
<head>
<meta http-equiv="Content-type"
content="text/html; charset=utf-8" />
<title>Pessoa</title>
</head>
<body>
<h1>Pessoa - Visão</h1>
<p>Nome: <?= $pessoa->getNome() ?></p>
<p>Fone: <?= $pessoa->getFone() ?></p>
</body>
</html>
Exemplo 2 – MVC com Dispatcher
 Usando um front-controller ou dispatcher
 Há um controlador principal (index.php) que
despacha as requisições para controladores e
ações específicos.
 Controladores e ações específicos são definidos
pelos parâmetros da URL do dispatcher:
 http://localhost/mvc/index.php/pessoa/mostra
 No nosso exemplo, o dispatcher:
 Instancia o controlador especificado
 Executa o método (ação) especificado do controlador
instanciado.
Testando a URL - testa_url.php
<?php
$parametros = explode('/',$_SERVER['REQUEST_URI']);
$controlador = $parametros[3];
$acao = $parametros[4];
$parametros = array_slice($parametros, 5);
?>
<html>
<head>
<meta http-equiv="Content-type"
content="text/html; charset=utf-8" />
<title>Testa URL</title>
</head>
<body>
<h1>Testa URL</h1>
<p>REQUEST_URI: <?= $_SERVER['REQUEST_URI'] ?></p>
<p>Controlador: <?= $controlador ?></p>
<p>Ação: <?= $acao ?></p>
<p>Demais parâmetros: <?php print_r($parametros); ?></p>
</body>
</html>
Dispatcher - index.php
<?php
$uri = str_replace('index.php/','',$_SERVER['REQUEST_URI']);
$parametros = explode('/',$uri);
$controlador = $parametros[2];
$acao = $parametros[3];
$parametros = array_slice($parametros, 4);
$arq_controlador = $controlador . '_controlador';
$classe_controlador = str_replace('_', ' ', $arq_controlador);
$classe_controlador = ucwords($classe_controlador);
$classe_controlador = str_replace(' ', '', $classe_controlador);
require_once($arq_controlador . '.php');
$obj = new $classe_controlador;
$obj->$acao($parametros);
?>
Controlador - pessoa_controlador.php
<?php
require_once('pessoa.php');
class PessoaControlador {
function mostra() {
$pessoa = new Pessoa('Maria','(86)3323-1234');
require_once('pessoa_visao.php');
}
}
?>
Problemas
 Podemos enviar requisições que não passam
pelo dispatcher.
 Seria mais interessante o dispatcher centralizar o
tratamento de todas as requisições.
 Enviar repetidamente 'index.php' para acessar
o dispatcher deixa a URL longa e ainda
diminui sua legibilidade.
 Seria melhor padronizarmos uma URL mais
resumida para definirmos o nome do controlador
e da ação.
Solução
 Uma solução bastante interessante para os
problemas abordados é a reescrita de URL.
 Com esse recurso podemos fazer a seguinte
convenção:
 Para a URL: http://localhost/mvc/pessoa/mostra
 Podemos dizer que:
 mvc é um diretório da nossa aplicação
 pessoa é o nosso controlador
 mostra é a nossa ação que será executada no
controlador.
Reescrita de URL
 Para usarmos reescrita de URL, precisamos habilitar
o módulo de reescrita do Apache:

No arquivo: C:xamppliteapacheconfhttpd.conf
descomente a seguinte linha:

LoadModule rewrite_module modules/mod_rewrite.so
 Depois disso, criamos nossas regras de reescrita no
arquivo .htaccess no diretório raiz da aplicação:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
Reescrita de URL
 No Ubuntu ainda é preciso alterar o AllowOverride
para All no arquivo /etc/apache2/sites-
available/default:
 No XAMPP isso já vem habilitado.
...
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
...
Flags de reescrita
 L – Last Rule
 Pára o processo de reescrita e não aplica
regras adicionais.
 Semelhante a um break do C, Java ou PHP.

Prog web 08-php-mvc

  • 1.
    Programação para WEB RegisPires Magalhães regispiresmag@gmail.com Implementando a Arquitetura MVC em PHP
  • 2.
    MVC – Modelo,Visão, Controlador  Model-view-controller (MVC) é um padrão de arquitetura de software.  Para que serve?  Separar papéis para: reduzir a complexidade e facilitar a manutenção, especialmente quando a aplicação fica grande. Também facilita a divisão de tarefas em uma equipe de trabalho.  Tornar aplicações mais flexíveis e extensíveis.  Permite inclusive a substituição da tecnologia de uma camada sem afetar as demais.
  • 3.
    MVC – Modelo,Visão, Controlador  Como surgiu?  Foi criado como padrão de projeto arquitetural usado em interfaces de usuário na linguagem Smalltalk.
  • 4.
    Arquitetura MVC Model (Dados) View (apresentação dos dados) Controller enviaentrada de dados exibe o modelo Consulta ou altera o modelo define que visão será exibida
  • 5.
    MVC – Modelo,Visão, Controlador  Modelo  Refere-se aos dados da aplicação.  Pode usar mecanismos de armazenamento persistente (bancos de dados) ou não.  Visão  Determina como o modelo vai ser mostrado ao usuário.  Controlador  Recebe interações do usuário e a partir delas, manipula o modelo e determina a visão a ser usada.  Pode alterar o modelo ou apenas consultá-lo para posterior apresentação deste modelo a partir de uma determinada visão.  Em outras palavras, faz o “meio-de-campo” entre o modelo e a visão.
  • 6.
    Arquitetura MVC –Resumo  Modelos – Dados;  Visões – Como os dados são apresentados;  Controladores – Recebe entrada de dados do usuário. Manipula o modelo e determina a visão para exibição do modelo.
  • 7.
  • 8.
    Exemplo 1 –MVC Super Simples  MVC bem simples para entendermos a divisão.  Modelo – pessoa.php  Visão – pessoa_visao.php  Controlador – pessoa_controlador.php
  • 9.
    Modelo - pessoa_modelo.php <?php classPessoa { private $nome, $fone; function __construct($nome, $fone) { $this->nome = $nome; $this->fone = $fone; } function getNome() { return $this->nome; } function getFone() { return $this->fone; } } ?>
  • 10.
    Controlador - pessoa_controlador.php <?php require_once('pessoa_modelo.php'); classPessoaControlador { function mostra() { $pessoa = new Pessoa('Maria','(86)3323-1234'); require_once('pessoa_visao.php'); } } $pc = new PessoaControlador(); $pc->mostra(); ?>
  • 11.
    Visão - pessoa_visao.php <html> <head> <metahttp-equiv="Content-type" content="text/html; charset=utf-8" /> <title>Pessoa</title> </head> <body> <h1>Pessoa - Visão</h1> <p>Nome: <?= $pessoa->getNome() ?></p> <p>Fone: <?= $pessoa->getFone() ?></p> </body> </html>
  • 12.
    Exemplo 2 –MVC com Dispatcher  Usando um front-controller ou dispatcher  Há um controlador principal (index.php) que despacha as requisições para controladores e ações específicos.  Controladores e ações específicos são definidos pelos parâmetros da URL do dispatcher:  http://localhost/mvc/index.php/pessoa/mostra  No nosso exemplo, o dispatcher:  Instancia o controlador especificado  Executa o método (ação) especificado do controlador instanciado.
  • 13.
    Testando a URL- testa_url.php <?php $parametros = explode('/',$_SERVER['REQUEST_URI']); $controlador = $parametros[3]; $acao = $parametros[4]; $parametros = array_slice($parametros, 5); ?> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title>Testa URL</title> </head> <body> <h1>Testa URL</h1> <p>REQUEST_URI: <?= $_SERVER['REQUEST_URI'] ?></p> <p>Controlador: <?= $controlador ?></p> <p>Ação: <?= $acao ?></p> <p>Demais parâmetros: <?php print_r($parametros); ?></p> </body> </html>
  • 14.
    Dispatcher - index.php <?php $uri= str_replace('index.php/','',$_SERVER['REQUEST_URI']); $parametros = explode('/',$uri); $controlador = $parametros[2]; $acao = $parametros[3]; $parametros = array_slice($parametros, 4); $arq_controlador = $controlador . '_controlador'; $classe_controlador = str_replace('_', ' ', $arq_controlador); $classe_controlador = ucwords($classe_controlador); $classe_controlador = str_replace(' ', '', $classe_controlador); require_once($arq_controlador . '.php'); $obj = new $classe_controlador; $obj->$acao($parametros); ?>
  • 15.
    Controlador - pessoa_controlador.php <?php require_once('pessoa.php'); classPessoaControlador { function mostra() { $pessoa = new Pessoa('Maria','(86)3323-1234'); require_once('pessoa_visao.php'); } } ?>
  • 16.
    Problemas  Podemos enviarrequisições que não passam pelo dispatcher.  Seria mais interessante o dispatcher centralizar o tratamento de todas as requisições.  Enviar repetidamente 'index.php' para acessar o dispatcher deixa a URL longa e ainda diminui sua legibilidade.  Seria melhor padronizarmos uma URL mais resumida para definirmos o nome do controlador e da ação.
  • 17.
    Solução  Uma soluçãobastante interessante para os problemas abordados é a reescrita de URL.  Com esse recurso podemos fazer a seguinte convenção:  Para a URL: http://localhost/mvc/pessoa/mostra  Podemos dizer que:  mvc é um diretório da nossa aplicação  pessoa é o nosso controlador  mostra é a nossa ação que será executada no controlador.
  • 18.
    Reescrita de URL Para usarmos reescrita de URL, precisamos habilitar o módulo de reescrita do Apache:  No arquivo: C:xamppliteapacheconfhttpd.conf descomente a seguinte linha:  LoadModule rewrite_module modules/mod_rewrite.so  Depois disso, criamos nossas regras de reescrita no arquivo .htaccess no diretório raiz da aplicação: RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L]
  • 19.
    Reescrita de URL No Ubuntu ainda é preciso alterar o AllowOverride para All no arquivo /etc/apache2/sites- available/default:  No XAMPP isso já vem habilitado. ... <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> ...
  • 20.
    Flags de reescrita L – Last Rule  Pára o processo de reescrita e não aplica regras adicionais.  Semelhante a um break do C, Java ou PHP.