Criando o roteamento do MVC - Entendendo o padrão MVC na prática – Parte 05 Artigo

Conheça os cursos gratuitos do WebDevBr! - Inscreva-se!


Este artigo foi publicado a 3 anos, 2 meses, 3 semanas, 3 dias atrás.

Será que esse é o artigo mais esperado? Não sei, mas sei que teve muita cobrança, e agradeço muito a Deus e vocês por isso! Obrigado por não me deixar desistir!

Agora sim, vamos lá:

O que é roteamento?

Quando falamos em MVC pensamos logo em Model para manipular os dados, a View pra exibir e o Controller pra decidir o que o model faz com os dados e quando a view deve exibir estes dados, mas ai eu te pergunto: Quem decide qual controller deve ser chamado?

Gostou deste artigo?

Receba atualizações semanais com novos artigos do WebDevBr e outras dicas!

Porque, segundo a regra de responsabilidade única e até mesmo os mais cretinos princípios de organização, você não vai criar um controller megasuperblasterhipergerenciadordasuaaplicacao, porque fica difícil de controlar tanto quanto ler a palavra anterior, o ideal é ter "módulos" que serão um conjunto de M+V+C.

Quem decidirá qual módulo deve ser carregado é a URL, que por sua vez irá parar nas mãos de uma classe que carregará seu controller. Essa classe fará o processo de roteamento!

Neste tutorial vamos usar o $SERVER["PATHINFO"] para definir as rotas, para quem não conhece, o PATH_INFO é aquele "caminho" de diretórios que fica logo o index.php em algumas aplicações, assim:

http://localhost/index.php/controller/view/id

Neste caso a variável $SERVER["PATHINFO"] irá retornar /controller/view/id, bem simples não é?

O que a maioria dos sistemas e frameworks do mercado fazem é colocar um .htaccess que vai remover o index.php da sua aplicação, isso faz com que a URL acima fique assim:

http://localhost/controller/view/id

Já passei o .htacces no segundo artigo desta série e falei sobre o PATH_INFO também.

Com isso entendido o que vamos fazer é criar em Library/Erik/Core o arquivo Router.php com o seguinte código:

<?php

namespace ErikCore;

class Router
{
    /*...*/
}

Prontinho, você já criou a sua classe, agora vamos rechear com o conteúdo. Eu criei 5 métodos, todos privados (private):

  • cleanUrl() - Remove a primeira barra e também será responsável por limpezas de caracteres na nossa url em caso de atualizações no nosso framework
  • urlArray() - Pega a nossa URL devidamente tratada no passo anterior e cria uma matriz (array) para o próximo método
  • setMvc() - Ele vai identificar qual "módulo" deve carregar na nossa aplicação a partir do Controller
  • loadMvc() - E por fim este método carrega a Controller específico e já indica uma função dentro deste controller (a action, no próximo artigo vou falar bastante disso).

É isso, claro que é um roteamento simples, mas vai funcionar bem para este exemplo.

Antes de continuar, crie um arquivo em App/Core chamado Config.php com o código abaixo:

<?php

namespace AppCore;

class Config
{

}

Assim mesmo, vazio, nosso roteamento também vai ler URLs previamente configuradas neste arquivo, de forma simples claro, nada de passar ids ou valores dinâmicos (não implementei isso neste roteamento, se você o fizer ou tiver paciência, muita paciência, eu faço com o maior prazer, um dia... kkkk).

E pra finalizar nosso roteamento, você é capaz de entender o arquivo?

<?php

/**
 * Roteamento define qual Controller, Model e View deve ser executado
 *
 * PHP version 5
 *
 * @category Erik
 * @package  Core
 * @author   Erik Figueiredo
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://www.webdevbr.com.br
 *
 */

namespace ErikCore;

use AppCoreConfig;

class Router
{

    use ErikUtilitiesRequest;
    use ErikUtilitiesInflector;

    private $config;
    private $url;
    public $mvc;
    private $params;


    public function __construct()
    {
        $this->config = new Config();

        $this->url=$this->request()['url'];
        $this->cleanUrl();
        $this->setMvc();
        $this->loadMvc();

    }

    private function cleanUrl($url=true, $params=false)
    {
        if ($url) {
            if (preg_match('/.{1,}(/){1}$/', $this->url)) {
                $this->url=substr($this->url, 0, -1);
            }
        }
        if ($params) {
            $this->params=substr($this->url, 1);
        }
    }

    private function urlArray()
    {
        if (preg_match('/.{1,}(/){1}$/', $this->url)) {
            $this->url=substr($this->url, 0, -1);
        }
    }

    private function setMvc()
    {
        if (isset($this->config->router[$this->url])) {
            $this->mvc=$this->config->router[$this->url];
        } else {
            $this->cleanUrl(false, true);
            $this->params=explode('/', $this->params);

            $this->params[0]=$this->upperCamelCase($this->params[0]);

            if ($this->url=='/') {
                $this->mvc=array(
                    'model'=>'Index',
                    'controller'=>'Index',
                    'action'=>'index',
                );
            } else {
                $this->mvc['controller']=$this->params[0];
                if (isset($this->params[1])) {
                    $this->mvc['action']=$this->params[1];
                }
            }
        }

        if (!isset($this->mvc['action']) || empty($this->mvc['action'])) {
            $this->mvc['action']='index';
        }
        if (!isset($this->mvc['controller']) || empty($this->mvc['controller'])) {
            $this->mvc['controller']='Index';
        }

    }

    private function loadMvc()
    {

        $controller=$this->mvc['controller'].'_Controller';
        $action=$this->mvc['action'];

        $controller = new $controller($this->mvc);
        $controller->$action();

    }
}

Note que estou usando também os nossos traits da aula passada (YEAH!!!), eu apenas passei o namespace deles no use e usei uma barra no começo (), essa barra vai informar para o autoload começar a buscar a partir da raiz da aplicação, sem ela ele iria somar o namespace do trait ao namespace da própria classe Router, é assim que usamos um trait.

Curiosidade: Router significa "roteador" que é quem executa o ato de rotear algo :D.

Próxima aula

No próximo artigo vamos criar o Controller e o Model principal e já mostrar algo na nossa tela, pra ser avisado da publicação desse tutorial cadastre-se ao lado.

Aqui os arquivos desta aula e o estudo completo


Cursos relacionados


* Parcelamento apenas cartão de crédito! Pode haver uma pequena variação no parcelamento em relação a simulações apresentadas!