+6

Programando em MVC com PHP

criado por Daniel Ribeiro em 16/08/2007 11:23am
Um dos módulos é o módulo de login, então teremos o loginModel, loginView, loginController e cada um desses serão classes que extenderão suas respectivas "classes mães". Exemplo:

<?php
class loginModel extends Model
{
    /**
     * Um metodo para verficiar a senha do usuario
     *
     * @param string $usuario
     * @param string $senha
     * @return bool
     */
    public function verificarSenhaUsuario($usuario, $senha)
    {
        $this->conectar();
        $sql = "SELECT * FROM usuarios WHERE usuario = $usuario AND senha = $senha";
        $resultado = $this->query($sql);
        $this->desconectar();
        return $resultado;
    }
}
?>

A classe de View do login, além de ter os métodos herdados do View principal, também tem seus próprios métodos:

<?php
class loginView extends View
{
    /**
     * Exibe a tela de login
     *
     */
    public function exibirTelaLogin()
    {
        $this->mostrarNaTela('login.tpl');
    }

    /**
     * Exibe a tela de erro
     *
     */
    public function exibirTelaErro()
    {
        $this->mostrarNaTela('erro.tpl');
    }

    public function exibirTelaLogado()
    {
        $this->mostrarNaTela('logado.tpl');
    }
}
?>

Agora sim iremos para a classe do controlador, que irá interagir com loginModel e loginView:

<?php
class loginController extends Controller
{
    // o loginController vai agregar loginModel e 
    // loginView entao criamos esses objetos aqui

    /**
     * @var loginModel
     */
    private $model;

    /**
     * @var loginView
     */
    private $view;

    public function __construct()
    {
        // instanciamos os objetos
        $this->model = new loginModel();
        $this->view = new loginView();
    }

    public function telaLogin()
    {
        // o metodo contrutor ja chama a view do 
        // login pra exibir a tela de login
        $this->view->exibirTelaLogin();
    }

    public function fazerLogin()
    {
        // tenta ver se o usuario colocou a senha certa
        if ($this->model->verificarSenhaUsuario($_POST['usuario'], $_POST['senha'])) {
            $this->gravaSessao();
            $this->log('usuario logou');
            $this->view->exibirTelaLogado();
        } else {
            $this->log('usuario tentou logar mas nao conseguiu');
            $this->view->exibirTelaErro();
        }
    }

    /**
     * Esse metodo é private, significando que 
     * so pode ser chamado dentro da classe
     */
    private function gravaSessao()
    {
        // grava a sessao usando session ou cookie
    }

    /**
     * Esse metodo é private, significando que
     * so podem ser chamando dentro da classe
     */
    private function apagaSessao()
    {
        // limpa a sessao ou cookie
    }
}
?>

Agora que já temos o nosso controlador loginController, temos que fazer com que ele seja instanciado e chamado pelo usuário, para isso teremos um arquivo de login onde irá fazer a instância do nosso controlador do login.

Algo como login.php, este arquivo será chamado pelo browser, onde fará a requisição da sua classe.

<?php
$objLogin = new loginController();

/*
verifica que metodo o browser esta chamando, 
se nao chamar nenhum metodo, exibo a tela de login
Desta forma se for chamado a url
http://www.seusite.com.br/login.php
ele vai chamar o metodo padrao telaLogin
*/

if (!$_REQUEST['action']) {
    $_REQUEST['action'] = 'telaLogin';
}

// agora eu executo o metodo passado via url
eval('$objLogin->' . $_REQUEST['action']);
?>

Pensando dessa maneira, você terá que fazer um arquivo para cada módulo do seu sistema, se o seu sistema tiver vários modulos, então terá vários arquivos:

login.php
usuarios.php (módulo de controle de usuários)
produtos.php (módulo de controle de produtos)
...

Se formos ver, todos os arquivos que fazem as requisições de suas classes são semelhantes, entao porque não generalizar e fazer em um arquivo? Um script que pode ser usado para chamar qualquer modulo do sistema?

<?php
// instancia o modulo
eval('$instancia = new ' . $_REQUEST['modulo'] . 'Controller();');

// define uma acao default
if (!$_REQUEST['action']) {
    // isso implica que todos os controllers 
    // terao que ter um metodo chamado acaoPadrao
    $_REQUEST['action'] = 'acaoPadrao';
}

// agora eu executo o metodo passado via url
eval('$instancia' . $_REQUEST['action']);
?>

Agora você tem um arquivo que pode chamar qualquer módulo / método do seu sistema, bastando especificar na url:

http://www.seusite.com.br/main.php?module=login
http://www.seusite.com.br/main.php?module=usuario
http://www.seusite.com.br/main.php?module=produtos

O que eu escrevi aqui é mais para fim didático de como construir aplicações usando o modelo MVC, e é claro que depois de você pegar o conceito, você vai aperfeicoar o mesmo ainda mais de um jeito que funcione melhor para o seu caso específico.

Comentários:

Mostrando 1 - 10 de 21 comentários
Achei muito bom o artigo, penço que se utilizarmos o PHP direto direcionado a um método de desenvolvimento no estilo MVC é mais confiável do que usar um framework diretamente pois você passa a ser dependente dele... com seus benefícios e problemas... Agraço a todos.
08/10/2012 8:43pm (~6 anos atrás)

Hm... Não gosto de seguir padrões pré-definidos.
Acho muito mais fácil criar um padrão próprio e seguí-lo :D
29/07/2012 9:59pm (~6 anos atrás)

Willian Silva disse:
Ainda não entendi para que serve o Smarty!
01/06/2009 11:21am (~9 anos atrás)

Dam disse:
Bom artigo.
20/11/2008 4:24am (~9 anos atrás)

Dam disse:
Bom artigo.
20/11/2008 4:24am (~9 anos atrás)

mnt bom o artigo, mas como o autor informa, é apenas conceptual.

Os menos experientes devem ter atenção e entender que o código que descrito, contem falhas graves de segurança...

<?php
...

// define uma acao default
if (!$_REQUEST['action']) {
// isso implica que todos os controllers
// terao que ter um metodo chamado acaoPadrao
$_REQUEST['action'] = 'acaoPadrao';
}

// agora eu executo o metodo passado via url
eval('$instancia' . $_REQUEST['action']);
?>

seria negativo se um usuário (mal intencionado) acedesse à página usando p/ex: ?action=login;phpinfo();

nesse caso é um exemplo inofensivo, mas acho que dá para terem ideia.

a solução é desenvolver um função + robusta de filtragem de parametros, aceitar apenas as conhecidadas, e usar o valor default para tudo o resto. (php.net/switch)
28/04/2008 4:02pm (~10 anos atrás)

fccd disse:
Muito bom essa class com extends...
Parabéns!
10/01/2008 11:03am (~10 anos atrás)

Adorei a métologia. Abriu minha cabeça. Sou programador iniciante e não conhecia essa estrutura. não foi difícil de entender. obrigado, em nome de todos da comunidade. Estou ciente de que posso contar com os artigos de qualidade desta cominidade. vlw :)
13/12/2007 8:02pm (~10 anos atrás)

ola. esse script e muito interessante e eu to utilizando ele num projeto. porem to tendo problemas com a linha eval('$objLogin->' . $_REQUEST['action']);... ta dando o seguinte erro q nao consigo resolver: "Parse error: syntax error, unexpected $end in C:\wamp\www\MVC\index.php(19) : eval()'d code on line 1
"... alguem pode me ajudar? Obrigado, Alysson
22/10/2007 7:33am (~11 anos atrás)

Ricardo Gama disse:
Muito bom script. seja de quem for a comunidade agradece... o pessoal tem que começar a abrir a cabeça pra mudar. essa forma de prgramar é muito boa... PARABÉNS
04/10/2007 12:59pm (~11 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)