Construindo um simples framework MVC com PHP.

Jardel Gonçalves
7 min readFeb 25, 2019

--

Neste artigo aprenderemos a construir um padrão de apresentação web sem uso de frameworks.

Código completo: https://github.com/JardelGoncalves/simple-framework-mvc-php

Motivação

A principal vantagem de usar o padrão MVC (acrônimo para Model View Controller) é a separação das responsabilidades que você tem entre as camadas. Cada camada possui sua responsabilidade referente a uma parte do trabalho da sua aplicação. Outra vantagem é a facilidade nas manutenções posteriores da sua aplicação, pois em aplicações onde apenas um arquivo “faz tudo” a manutenção se torna uma tarefa complicada e cara.

Requisitos

  • PHP 7.2 (e o drive pgsql)
  • PostgreSQL

Criando o Banco de dados

Para que nossa aplicação funcione corretamente, devemos criar nosso banco de dados. Acesse o PostgreSQL via pgAdmin ou terminal, crie um database com o nome mvc_db e com a seguinte tabela:

CREATE TABLE users (
id SERIAL,
name VARCHAR(100)
);

A aplicação

Com o nosso framework, iremos desenvolver uma simples aplicação que lista todos os usuários no banco de dados PostgreSQL e buscar o usuário por ID.

A aplicação é extremamente simples, porém o foco está na construção do framework que pode ser utilizado em outras aplicações mais complexas.

Para iniciar o projeto, podemos criar uma pasta/diretório em sua máquina com o nome do seu projeto. Neste artigo chamaremos de simple-mvc e criaremos a seguinte estrutura de diretório.

simple-mvc
├── Application/
│ ├── controllers/
│ │ ├── Home.php
│ │ └── User.php
│ ├── core/
│ │ ├── App.php
│ │ ├── Controller.php
│ │ └── Database.php
│ ├── models/
│ │ └── Users.php
│ ├── views/
│ │ ├── home/
│ │ │ └── index.php
│ │ └── user/
│ │ ├── index.php
│ │ └── show.php
│ ├── .htaccess
│ └── autoload.php

└── public/
├── assets/
│ ├── css/
│ │ └── bootstrap.min.css
│ ├── img/
│ │ └── erro.png
│ └── js/
│ ├── bootstrap.min.js
│ └── jquery.slim.min.js
├── .htaccess
└── index.php

O código fonte do nosso framework ficará em simple-mvc/Application/ . Quando o usuário acessar nossa aplicação, o diretório raiz será simple-mvc/public. A baixo, explicaremos a responsabilidade de cada diretório e arquivo em simple-mvc/Application.

  • controllers/ → Este diretório armazenará todos os controladores da aplicação que recebe os dados informados pelo usuário e decide o que fazer com eles e cada método deve realizar uma ação ou chamar view. Além disso, toda classe criada herda os métodos da classe Controller do arquivo armazenado em Application/core/Controller.php que será discutido em breve.
  • core/ → Neste diretório será armazenado três arquivos: App.php que é responsavel por tratar a URL decidindo qual controlador e qual método deve ser executado; Controller.php responsável por chamar o model, view e pageNotFound que são herdados para as classes no diretório Application/controllers; E por último, o arquivo Database.php que armazena a conexão com o banco de dados.
  • models/ → Aqui fica a lógica das suas entidades, no nosso caso usaremos classes que irá interagir com o banco de dados e fornecer tais dados para as views.
  • views/ → As views serão responsável por interagir com o usuário. Uma das suas principais características é que cada view sabe como exibir um model.
  • .htaccess → Neste arquivo, apenas negaremos a navegação no diretório com a opção Options -Indexes.
  • autoload.php → Neste arquivo, carregaremos de forma automática todas as classes no diretório Application/.

Sem mais delongas, vamos para o código 🙂.

Navegando pelo código

O primeiro arquivo e um dos mais importante é Application/core/App.php que tem a responsabilidade de obter a URL, dividi-la por / e obtendo um array. O primeiro índice deste array contém o controller que iremos instanciar; O segundo índice contém o método que iremos chamar do controller que instanciamos e o restante são considerados como parâmetros do método. Abaixo você pode analisar o código:

Application/core/App.php

Outro arquivo importante, é Application/core/Controller que fornece para as classes filhas (as classes em Application/controllers/*) os métodos para instanciar um model dinâmicamente, exibir uma determinada view passando para a mesma os dados em um array que podem ser acessado pela variável $data. Em casos de métodos ou controladores não encontrados (informado pelo usuário) é chamado o método pageNotFound fornecido por essa classe. Abaixo está o código da mesma:

Application/core/Controller.php

Como citado anteriormente, usaremos o PostgreSQL como banco de dados e abaixo é apresentado a classe de conexão com o banco de dados presente em Application/core/Database.php:

Application/core/Database.php

Em Application/models criaremos um model que chamaremos de Users.php contendo apenas métodos estáticos e que interagem com o banco de dados, sendo um método que retorna todos os usuários na base de dados e o outro retorna apenas um usuário que possui um determinado id. Veja o código deste arquivo abaixo:

Application/models/Users.php

O prómixo arquivo é Application/controllers/Home.php que simplesmente herda de Controller todos os métodos. Na classe Home podem ser criados métodos que se responsabilize por uma determinada ação/processamento que inclui chamar uma determinada view (interface que interagem o usuário). No caso de Home existe o método index que é chamado toda vez em que o usuário informa na URL por exemplo http://meusite.com/<controller>/index substituindo o valor <controller> por exemplo por home ou quando é acessado http://meusite.com/<controller>/ e no caso de home, por padrão pode ser chamado quando for acessado a URL http://meusite.com (exemplo). Veja o código desta classe abaixo:

Application/controllers/Home.php

Normalmente um controller se responsabiliza por um model. No nosso caso, temos o model Users e o controlador que se responsabiliza pelo mesmo é User que pode ser encontrado em Application/controllers/User.php que possui dois métodos:

  • index() → Que é chamado toda vez que a URL http://<ip-ou-domino>/user/index ou http://<ip-ou-domino>/user/ é acessada e é retornado para a view ( Application/views/user/index.php ) todos os usuários no banco de dados em uma variável $data que na verdade é um array associativo.
  • show() → É chamado quando o usuário acessa http://<ip-ou-domino>/user/show/<id>, caso não seja informado um ID é retornado a página de erro.

Veja o código da classe abaixo:

Application/controllers/User.php

Com práticamente todas as classes criadas, devemos criar apenas os arquivos da views e para não deixar mais longo (porque já está! 😅) apresentaremos apenas a view Application/views/user/show.php e as demais views, os arquivos .htaccess e arquivos estáticos (css, imagens e js) você pode acessar o link do repositório que está no inicio deste artigo.

Como citado anteriormente, no arquivo Application/core/Controller.php o método view() recebe dois argumentos, o primeiro é a view que neste caso é a Application/views/user/show.php usaremos apenas o caminho após o diretório views/ ou seja, apenas user/show sem a extensão .php e o segundo argumento é os dados que serão usados na view e que no caso será o usuário que possui um determinado id.

Esses dados são passados para em um array associativo com a chave 'user', você pode observar essas informações no controlador User citado anteriormente. É ideal entrar em detalhes deste método, pois na view usaremos uma variável (array) $data['user'], todo e qualquer dado que for passado no array da view ele pode ser obtido através da variável $data com a chave informada.

Como o método do model Users retorna um array, nós podemos acessar os dados deste array ($data['user']) com um foreach como podemos observar no código da view user/show abaixo:

Application/views/user/show.php

O próximo arquivo que fará todas essas classes funcionar, é o autoload.php encontrado na raiz do diretório Application. A sua principal responsabilidade é carregar de forma automática as classes utilizando SPL (Standard PHP Library). Abaixo podemos observar seu código:

Application/autoload.php

Está quasse tudo pronto!

Para finalizar e ser possivel testar nosso simples framework MVC, precisamos criar um arquivo index.php na raiz do diretório public. Toda vez que o usuário acessar uma rota em nossa aplicação este arquivo será responsável por fazer toda a aplicação funcionar.

Este arquivo é bem simples, contém TAGs html que serão tudo aquilo em comum entre as views, ou seja, o cabeçalho e o rodapé da página, e no centro deste arquivo (que seria a parte do conteudo de cada view que difere entre elas) incialmente incluimos o nosso autoload.php e instanciamos um objeto App, ele é o principal arquivo do nosso framework e que faz toda a lógica da URL, chamada dos métodos, dos controladores e etc...

public/index.php

Quase lá!

Caso você queria testar no Apache, lembre-se apenas de habilitar o módulo de reescrita. Porém, utilizaremos o servidor interno do PHP para testar. Na raiz do seu projeto (no meu caso, simple-mvc) digite o seguinte comando:

php -S localhost:8080 -t public/

Feito isso, podemos testar!

Testando

Primeiro teste que iremos fazer é acessar a raiz do nosso site, ou seja, http://localhost:8080. Ao acessar é exibido a seguinte página:

No segundo teste, vamos acessar http://localhost:8080/user/. Neste caso ele chamará o método index() do controlador User que retornará uma página listando todos os usuários contidos no banco de dados. Veja:

E por último, acessaremos http://localhost:8080/user/show/<id> informando um id que no caso será o 2 e deve retornar uma view contendo apenas um usuário com aquele determinado id.

É isso galera! Espero ter ajudado.

Abraços ♡

--

--