I'm trying to understand the MVC
pattern and I've created an example with CRUD
of users (with login), but I'm not sure if it's the best way I've created it.
Here are some pages and the download link for the project:
index.php
<?php
/**
* Created by PhpStorm.
* User: Leonardo Vilarinho
* Date: 10/03/2016
* Time: 00:55
*/
// include da camada Controller
require_once 'controller/ControllerLogin.php';
// Se variáveis de sessão tiverem ativas então já fez o login
if(isset($_SESSION['usuario']) and isset($_SESSION['id']))
{
// define ato como listar-usuarios (primeira página apos login)
$_GET['ato'] = (isset($_GET['ato'])) ? $_GET['ato'] : "listar-usuarios" ;
}
// se login não tiver sido feito
else
{
// o ato será entrar
$_GET['ato'] = "entrar";
}
//instancia uma nova classe Controller (do arquivo ControllerLogin )
$controller = new ControllerLogin();
//chama método do controller
$controller->requerir();
ControllerLogin.php
<?php
/**
* Created by PhpStorm.
* User: Leonardo Vilarinho
* Date: 10/03/2016
* Time: 00:56
*/
// include em camada model
require_once 'model/ModelLogin.php';
class ControllerLogin
{
// variavel para ser a camada model
private $model = NULL;
// metodo contrutor, sempre que a classe ControllerLogin for criada ele executará esse metodo
public function __construct()
{
//instancia uma classe da camada Model
$this->model = new ModelLogin();
}
// método para encaminhar ação do usuário
public function requerir()
{
// pega o get do link (exemplo index.php?ato=entrar) ato é a ação e entrar é o valor da ação
$ato = (isset($_GET['ato'])) ? $_GET['ato'] : NULL;
try
{
// verifica e chama metrodo para fazer ação selecionada
if(!$ato or $ato == "entrar")
{
$this->fazerLogin();
}
else if($ato == "listar-usuarios")
{
$this->listarUsuarios();
}
else if($ato == "novo-usuario")
{
$this->novoUsuario();
}
else if($ato == "editar-usuario")
{
$this->editarUsuario();
}
else if($ato == "apagar-usuario")
{
$this->apagarUsuario();
}
else if($ato == "sair")
{
$this->sairSistema();
}
}
catch(Exception $ex)
{
}
}
// método como um goto, para ir para uma página especifica
private function irPara($pagina)
{
header("Location:".$pagina);
}
// método para o ato entrar
private function fazerLogin()
{
// titulo da página
$titulo = "Login MVC";
// se formuĺário de login foi enviado (quando usuário clica em Entrar no login)
if(isset($_POST['login-requerido']))
{
try
{
// cria uma variavel login para armazenar o resultado do metodo preparaLogin do model
// aqui ele chama o métolo preparaLogin do arquivo ModelLogin passando os dados informados pelo usuario
$login = $this->model->preparaLogin($_POST['nome'], $_POST['senha']);
// se login for true (foi validado)
if($login)
{
// ele vai para a página com o ato de listar usuarios
$this->irPara("index.php?ato=listar-usuarios");
}
else
{
// define um erro
$erro = "Usuário ou senha inválido(a).";
}
}
catch(ValidationException $ex)
{
$erro = $ex->pegarErros();
}
}
// inclue (escreve) arquivo entrar.php na página atual
include 'view/entrar.php';
}
// método para o ato listar-usuarios
private function listarUsuarios()
{
// define titulo da página
$titulo = "Listagem de Usuários";
try
{
// cria uma variavel lista para pegar o retorno do metodo listarTodos de model "usuarios" é a tabela do banco
$lista = $this->model->listarTodos("usuarios");
// se lista tiver vazia ou nao foi declarada
if(empty($lista) or !$lista)
{
// define um erro
$erro = "Sem usuários";
}
}
catch(ValidationException $ex)
{
$erro = $ex->pegarErros();
}
// inclue (escreve) arquivo listar-usuarios.php na página atual
include 'view/listar-usuarios.php';
}
// método para o ato novo-usuario
private function novoUsuario()
{
// define titulo da página
$titulo = "Adicionar Usuário";
// se usuario clicou no botao Criar do formulario
if(isset($_POST['novousuario-requerido']))
{
try
{
// cria uma variavel cadastro para armazenar o resultado do metodo preparaUsuarioNovo do model
// aqui ele chama o métolo preparaUsuarioNovo do arquivo ModelLogin passando os dados informados pelo usuario
$cadastro = $this->model->preparaUsuarioNovo($_POST['nome'], $_POST['senha']);
// se fez o cadastro de usuário com sucesso
if($cadastro)
{
// volta para a página de listagem
$this->irPara("index.php?ato=listar-usuarios");
}
else
{
// define um erro
$erro = "Houve um erro ao gravar o usuário.";
}
}
catch(ValidationException $ex)
{
$erro = $ex->pegarErros();
}
}
// inclue (escreve) arquivo novo-usuario.php na página atual
include 'view/novo-usuario.php';
}
// método para o ato editar-usuario
private function editarUsuario()
{
// define um titulo
$titulo = "Editar Usuário";
// pega id que está no link (index.php?ato=editar-usuario&id=4) id é 4
$id = (int) $_GET['id'];
// pesquisa usuario a ser editado pelo id e coloca em $usuario
$usuario = $this->model->preparaUsuarioId($id);
// se formulario de editar-usuario foi enviado
if(isset($_POST['editarusuario-requerido']))
{
try
{
// chama método do model que edita um usuario
$edicao = $this->model->preparaUsuarioEditar($_POST['id'], $_POST['nome'], $_POST['senha']);
//se editou com sucesso
if($edicao)
{
// volta para listar usuarios
$this->irPara("index.php?ato=listar-usuarios");
}
else
{
//define um erro
$erro = "Houve um erro ao editar o usuário.";
}
}
catch(ValidationException $ex)
{
$erro = $ex->pegarErros();
}
}
// inclue (escreve) arquivo editar-usuario.php na página atual
include 'view/editar-usuario.php';
}
// método para o ato apagar-usuario
private function apagarUsuario()
{
// titulo da página
$titulo = "Editar Usuário";
// pega id que esta no link " href="index.php?ato=apagar-usuario&id={$lista[$item]['id']}" "
$id = (int) $_GET['id'];
try
{
// chama metodo de apagar na camada model
$tentativa = $this->model->preparaUsuarioApagar($id);
// se apagou
if($tentativa)
{
// vai para listagem
$this->irPara("index.php?ato=listar-usuarios");
}
else
{
// exibe um erro
$erro = "Houve um erro ao apagar o usuário.";
}
}
catch(ValidationException $ex)
{
$erro = $ex->pegarErros();
}
}
// método para o ato sair
private function sairSistema()
{
// destroi variaveis de sessão
unset($_SESSION['id']);
unset($_SESSION['usuario']);
// destroi sessao
session_destroy();
//vai para página de login
$this->irPara("index.php?ato=entrar");
}
}
ModelLogin.php
<?php
/**
* Created by PhpStorm.
* User: Leonardo Vilarinho
* Date: 10/03/2016
* Time: 01:10
*/
// include na biblioteca de CRUD
require_once 'libs/crud.php';
// inicia sessao
session_start();
class ModelLogin
{
// variavel privada para chamar o crus
private $crud = NULL;
// metodo contrutor, sempre que a classe ModelLogin for criada ele executará esse metodo
public function __construct()
{
// instancia um novo crud
$this->crud = new CRUD();
}
// método que pega nome e senha do login
public function preparaLogin($nome, $senha)
{
// aqui tem a validação dos campos (de tamanho etc)
// retorna o resultado do método efetua login
return $this->efetuaLogin($nome, $senha);
}
// metodo que verifica login (pega dados no banco e compara com os recebidos)
private function efetuaLogin($nome, $senha)
{
try
{
// chama o metodo consult do crud na tabela usuarios onde a coluna usuario é igual nome
// e armazena em usuario
$usuario = $this->crud->consult("usuarios", "*", "usuario = {$nome}");
// se o nome digitado for igual a coluna 'usuario' do primeiro resultado da consulta
// e o a senha equivale a criptografada do banco
if($nome == $usuario[0]['usuario'] and password_verify($senha, $usuario[0]['senha']))
{
// cria variaveis de sessao (que sao destuidas somente quando o navegadore fecha)
$_SESSION['id'] = $usuario[0]['id'];
$_SESSION['usuario'] = $usuario[0]['usuario'];
return true;
}
else
{
return false;
}
}
catch(CRUDException $ex)
{
return false;
}
}
// método que pega a tabela a ser listada
public function listarTodos($tabela)
{
// retorna resultado da execução
return $this->executarConsulta($tabela);
}
// método para consultar em uma tabela
private function executarConsulta($tabela)
{
try
{
// retorna um array com o resultado da pesquisa de todas as colunas (*)
return $resultado = $this->crud->consult($tabela, "*");
}
catch(CRUDException $ex)
{
return false;
}
}
// método que pega dados para criar um novo usuario
public function preparaUsuarioNovo($nome, $senha)
{
// retorna resultado do insert
return $this->cadastraUsuario($nome, $senha);
}
// metodo que cadastro usuario no banco
private function cadastraUsuario($nome, $senha)
{
try
{
// consulta no banco se tem um usuario com o mesmo nome
$verifica = $this->crud->consult("usuarios", "*", "usuario = {$nome}");
// se nao tiver encontrado um usuario igual
if(empty($verifica) or $verifica == null)
{
// insere novo usuario
$this->crud->insert
(
"usuarios",
array("usuario", "senha"),
array($nome, password_hash($senha, PASSWORD_DEFAULT))
);
return true;
}
// se usuario ja tiver cadastrado
else
{
return false;
}
}
catch(CRUDException $ex)
{
return false;
}
}
// metodo que pega id do usuario a ser editado (para pegar os dados dele e colocar na pagina de edição)
public function preparaUsuarioId($id)
{
// retorna resultado da procura
return $this->procuraUsuarioId($id);
}
// procura um usuario por id
private function procuraUsuarioId($id)
{
try
{
// $consulta vai receber um array com os dados daquele usuario
$consulta = $this->crud->consult("usuarios", "*", "id = {$id}");
// retorna o array ou false se nao achou usuario
return (!empty($consulta)) ? $consulta : false;
}
catch(CRUDException $ex)
{
return false;
}
}
// pega novas dados do usuario a ser editado
public function preparaUsuarioEditar($id, $nome, $senha)
{
// retorna o resultado da edição
return $this->editarUsuario($id, $nome, $senha);
}
// edita usuario
private function editarUsuario($id, $nome, $senha)
{
try
{
// retorna true ou false se editou ou nao o usuario
return $this->crud->update
(
"usuarios",
array("usuario", "senha"),
array($nome, password_hash($senha, PASSWORD_DEFAULT)),
"id = {$id}"
);
}
catch(CRUDException $ex)
{
return false;
}
}
// pega id do usuario a ser apagado
public function preparaUsuarioApagar($id)
{
return $this->apagarUsuario($id);
}
//metodo para apagar usuario
private function apagarUsuario($id)
{
try
{
// retorna true ou false de acordo com o sucesso
return $this->crud->delete
(
"usuarios",
"id = {$id}"
);
}
catch(CRUDException $ex)
{
return false;
}
}
}
login.php
<?php
/**
* Created by PhpStorm.
* User: Leonardo Vilarinho
* Date: 10/03/2016
* Time: 00:59
*/
// inclui arquivo do template (o inicio da pagina)
include_once 'template/header.php';
// se tiver erro armazena numa variavel o erro do Controller em um painel vermelho
$printErro = (isset($erro))
? "<div class='text-danger text-center'><strong>{$erro}</strong></div>"
: "";
?>
<section class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-primary">
<form method="post">
<div class="panel-heading">
<strong><?php echo $titulo; ?></strong>
</div>
<?php echo $printErro; ?>
<div class="panel-body">
<input name="nome" required placeholder="Usuário" type="text" class="form-control"/>
<input name="senha" required placeholder="Senha" type="password" class="form-control" />
<!-- informa formulario a ser enviado desta página e quando ele foi enviado -->
<input name="login-requerido" value="1" type="hidden" />
</div>
<div class="panel-footer">
<input value="Entrar" type="submit" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</section>
<?php
// inclui fim do template
include_once 'template/scripts.php';
include_once 'template/end.php';
list-users.php
<?php
/**
* Created by PhpStorm.
* User: Leonardo Vilarinho
* Date: 10/03/2016
* Time: 14:16
*/
// inclui arquivo do template (o inicio da pagina)
include_once 'template/header.php';
?>
<section class="row">
<div class="panel text-right">
<a class="btn btn-primary" href="index.php?ato=novo-usuario" ><i class="fa fa-plus"> Novo</i></a>
</div>
<div class="col-md-12">
<table class="table table-responsive table-bordered table-hover">
<!-- cabeça da tabela -->
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Ação</th>
</tr>
</thead>
<?php
// enquanto tiver item na lista do metodo listarUsuarios do controller
for($item = 0; $item < count($lista); $item ++)
{
/*
botao editar tem um ato de editar-usuario e o id do usuario a editar
o botao apagar chama um javascript de confimação e o botao sim chama o ato
apagar-usuario e o id do usuario
*/
echo <<<ITEM
<tr>
<td>{$lista[$item]['id']}</td>
<td>{$lista[$item]['usuario']}</td>
<td>
<a class="btn btn-warning" href="index.php?ato=editar-usuario&id={$lista[$item]['id']}" ><i class="fa fa-pencil"></i></a>
<a class="btn btn-danger apagar" id="{$lista[$item]['id']}" ><i class="fa fa-trash"></i></a>
<div class="text-right oculto confirmacao{$lista[$item]['id']}">
<span>Deseja realmente excluir?</span>
<a class="btn btn-danger nao" id="{$lista[$item]['id']}" >Não</a>
<a class="btn btn-success" href="index.php?ato=apagar-usuario&id={$lista[$item]['id']}" >Sim</a>
</div>
</td>
</tr>
ITEM;
}
?>
</table>
</div>
</section>
<?php
//inclui scripts do template
include_once 'template/scripts.php';
//adiciona script somente a essa pagina
echo "<script src='js/excluir-usuario.js' type='text/javascript'></script>";
//inclui final do template
include_once 'template/end.php';
Doubt is for example expanding, creating a crud of notes for example without having to put in ControllerLogin
and ModelLogin
. That is, create new classes for other objects without being users (login). What if this way I used is correct?
Download the project: login.zip file