A escolha das ferramentas - Entendendo o padrão MVC na prática Artigo

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


Este artigo foi publicado a 10 meses, 1 semana, 5 dias atrás.

Seguindo com nossa série de artigos sobre MVC, desta vez, vamos instalar e configurar a estrutura do nosso projeto, quero falar um pouco do motivo da escolha de cada ferramenta e se possível, algumas alternativas, neste artigo vou falar um pouco sobre cada componente e também já criar os arquivos iniciais, responsáveis por retornar os dados de configuração.

Os outros artigos desta série.

O Composer

Eu simplesmente não imagino mais a minha vida sem o Composer, como pude programar por tanto tempo sem ele!

Gostou deste artigo?

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

Se você quer mais informações sobre ele, tem um curso completo e de graça de Composer aqui no WebDevBr.

Você vai apenas precisar baixar o composer no site oficial, colocar no diretório raiz do projeto e apenas rodar um php composer.phar install via linha de comando com este arquivo composer.json abaixo (crie e salve ao lado do composer.phar):

{
    "autoload": {
        "psr-4": {
            "WebDevBr\\Mvc\\":"src"
        }
    },
    "require": {
        "slim/slim": "^3.1",
        "symfony/yaml": "^3.0",
        "illuminate/database": "^5.2",
        "twig/twig": "^1.24"
    },
    "require-dev": {
        "robmorgan/phinx": "^0.5.1",
        "filp/whoops": "^2.0"
    }
}

Tem muitoa coisa acontecendo aqui, mas vou separar em 3 partes, autoload, require e require-dev.

autoload

O autoload informa que o Composer deve carregar (com include/require) os arquivos de classe que estão dentro do diretório src, mas somente quando eu informar que o namespace começa com WebDevBr\Mvc.

Namespace é usado para complementar o nome de uma classe de forma a separar em categorias e subcategorias, no nosso caso, em nome do forncedor (quem desenvolveu, por exemplo) e pacote (a biblioteca de código, no nosso exemplo, Mvc).

require

Aqui estão os pacotes que eu vou precisa para que meu código funcione, por exemplo slim/slim (Slim Framework) que vou usar para identificar cada página da aplicação.

Vou descrever cada um logo mais.

require-dev

E estes são os pacotes para me auxiliar no desenvolvimento, eles não serão obrigatórios para o funcionamento da aplicação.

Vou adicionar um --dev no título de cada um abaixo, assim você vais saber assim que olhar.

Slim Framework (slim/slim)

O Slim Framework é um micro framework muito simples de usar, a ideia de um micro framework é que seja minimalista, ou seja, com poucos recursos, assim podemos incluir o que precisarmos pouco a pouco e também trabalhar mais com o bom e velho PHP sem um monte de recursos mascarando a coisa toda (sei que pareceu algo ruim, mas eu também gosto de frameworks incrementados, chamamos eles de full stack).

Existe muita dificuldade hoje em dia em se usar um micro framework, já que frameworks full-stack (como Laravel, CakePHP e Zend Framework) já trazem quase tudo o que precisamos sem que programador tenha muito trabalho (e isso gera preguiça e devs com conhecimento raso, mas a culpa é sua e não da ferramenta).

Tire um framework de um programador e saberá quem ele é!

Outras opções - Silex - Lumen

Symfony Yaml (symfony/yaml)

O Symfony Yaml e um componente do Symfony para trabalhar com arquivos yaml, vamos usar para ler as configurações do nosso projeto e poder alterar tudo em um único lugar, sem ter que ficar abrindo ou procurando estas configurações dentro da aplicação.

Ele já seria instalado por outros componentes, mas assim eu deixo implícito que estou usando o componente.

Illuminate Database (illuminate/database)

Aqui temos o famoso Eloquente, o ORM do Laravel, que faz parte do Illuminate Database, que é do Laravel, que traz o Famoso Eloquente, dentro do Illuminate Database... Ta, acho que você entendeu.

Ele é interessante pois tem um bom suporte a bancos de dados diversos, só conecta no banco de dados quando é realmente necessário (nada de conectar e esperar que talves você use), seguro e é muito simples de usar.

Um ORM (ou Object Relational Mapper) é responsável por transportar a base relacional dos bancos como MySql e PostGreSql para uma estrutura voltada a orientação a objetos, que é o nosso caso. Cada registro vira uma entidade, que na verdade é um objeto com cada campo do registro em uma variável de instância, isso possíbilita, por exemplo, que você altere os registros automáticamente direto na entidade.

Só para registro, uma variável de intância é aquela dentro da classe:

class Objeto
    {
        protected $variavelDeInstancia;
    }

O Illuminate Database já traz um Query Builder (para você não escrever sql, ele se preocupa em gerar o sql compatível para o banco de dados que você está usando).

Outras opções - Doctrine ORM e Doctrine DBAL - CakePHP ORM - Propel

Twit (twig/twit)

Este será o nosso template engine, e será responsável por montar nosso HTML, a grande vantagem do Twig é a possibilidade de não usarmos nenhum PHP para renderização (ou quase), ele tem tags simples e intuitivas próprias que agilizam nossa vida ao tempo que evitam retornos indesejádos, como renderizar HTML em lugares que isso não deveria acontecer (falha de segurança).

Outras opções - Mustache - Plates - Lex

Phinx (robmorgan/phinx) --dev

O Phinx é um gerenciador de migrações para o banco de dados, ou seja, em vez de arquivos sql você criar arquivos PHP que rodam comandos no banco para criar tabelas, alterar colunas ou remover. A ideia é que a medida que você evolua sua aplicação as alterações no banco de dados fiquem registradas dando a possibilidade de fazer rollback (voltar a uma versão anterior), automatizar o deploy (deploy é publicar o projeto, imagine, com um comando ele enviar os arquivos e já atualiza o banco se for necessário).

Ele possui também o recurso de seeds (sementes, traduzido do inglês) para inserir, por exemplo, os dados iniciais da aplicação ou dados de teste.

O Phinx é muito completo e da acesso a muitas coisas, como chaves estrangeiras, por exemplo (sempre me perguntam isso).

Whoops (filp/whoops) --dev

Erros!!!! ERROS!!!! Malditos erros!!!!!!

O Whoops é um componente que transforma a exibição de erros da sua aplicação em uma página bonita, organizada e com muita informação para te ajudar a resolver e identificar rapidamente o que pode ter acontecido, normalmente eu uso junto com o Monolog (para registrar o erro em um arquivo), mas eu vou usar só ele aqui.

O Composer

O Composer é bem simples de usar, ele tem até um instalador para Windows e passos para que possa ser usado globalmente no Linux.

Depois de criar o arquivo composer.json, basta rodar um composer install no diretório que ele se encontra (via terminal, cmd, console, dos, como você quiser chamar).

Configurações da aplicação

Assim que terminar de instalar tudo com o composer, você vai acabar com 2 arquivos e um diretório (composer.json, composer.lock e vendor), a primeira coisa a fazer é criar nosso arquivo yaml de configuração usando o Phinx, pra isso é só rodar o phinx init

vendor/bin/phinx init

Isso vai gerar um arquivo phinx.yml na raiz do projeto, vamos usar este arquivo para guardar nossas configurações.

Na sequência vamos criar um arquivo chamado bootstrap.php, também na raiz do projeto, ele será responsável por configurar tudo o que for necessário para trabalharmos.

Ele terá este conteúdo:

<?php

include __DIR__.'/vendor/autoload.php';

Este arquivo que carreguei é o autoloader do Composer, ele cuida de incluir todos os arquivos e classes que usarmos automaticamente, e isso já ajuda muito.

Dentro do diretório src vou criar um arquivo chamado Config.php (preste atenção no C maiúsculo). e dentro dele o seguinte conteúdo:

<?php

namespace WebDevBr\Mvc;

use Symfony\Component\Yaml\Parser;

class Config
{
    private static $config;

    public static function init()
    {
        if (!self::$config) {
            $yaml = new Parser();
            self::$config = $yaml->parse(file_get_contents(__DIR__.'/../phinx.yml'))['environments'];
        }
    }

    public static function get($path = null)
    {
        if ($path and isset(self::$config[$path])) {
            return self::$config[$path];
        } else if ($path and !isset(self::$config[$path])) {
            return null;
        }
        return self::$config;
    }
}

Toda classe que criarmos terá um namespace, isso se refere ao diretório aonde está armazenado, o Composer usa isso para o autoload.

Em seguida eu informei um use Symfony\Component\Yaml\Parser;, ele diz que eu vou usar esta classe no arquivo e agora eu não preciso escrever tudo isso quando usar, apenas o ultimo item (o Parser).

Note que no método init() eu usei um if (!self::$config), isso é para garantir que esta configuração não será sobrescrita durante a execução da aplicação, ele só irá realizar esta tarefa uma única vez.

Dentro do if eu apenas instancio o Parser e uso junto com filegetcontents() para trazer o conteúdo do arquivo de configuração, tudo isso gera um array com todos os dados dentro do phinx.yml.

Para trazer estes dados eu criei um método get($path =null), assim eu posso trazer o array completo (não informando o $path) ou apenas um item, da forma que eu precisar, note que se eu informar um item que não existe ele não da erro, apenas retornar null.

Agora, voltando ao bootstrap.php, em baixo do include que está presente atualmente vou incluir o seguinte:

use WebDevBr\Mvc\Config;

Config::init();

if (Config::get('debug')) {
    //aqui eu configuro o Whoops
}

Novamente usei o use para informar a classe que quero (neste caso a minha Config dentro de src) e em baixo rodei o comando init() para lermos os dados.

Agora veja que eu usei o Config::get('debug'), ele deve retornar null, já que nao existe este item no phinx.yml, vamos criar?

paths:
        migrations: %%PHINX_CONFIG_DIR%%/db/migrations
        seeds: %%PHINX_CONFIG_DIR%%/db/seeds

environments:
        default_migration_table: phinxlog
        debug: true <--aqui
        //resto do arquivo

Apenas inclua o debug: true, dentro de environments, não altere mais nada e ignore o <--aqui e o //resto do arquivo. Mas porque em environments?

Lembra do Config.php? Dentro dele tem a seguinte linha, que faz parte do método init():

self::$config = $yaml->parse(file_get_contents(__DIR__.'/../phinx.yml'))['environments'];

Olha ali no final, eu já passo a configuração dentro do environments, por isso lembre-se que todas as suas configurações devem estar dentro deste nó do arquivo yml.

Erros com o Whoops

Ainda no bootstrap.php coloque este código dentro do if (Config::get('debug')):

$run = new Whoops\Run;
$handler = new Whoops\Handler\PrettyPageHandler;
$run->pushHandler($handler);
$run->register();

Simples assim! Já configuramos o Whoops, e ele só será executado quando estivermos em desenvolvimento, quando publicar o projeto na internet, basta apenas trocar o debug pra false ou excluir do yml para desativar o Whoops.

Da uma olhada na página oficial pra ver como fica o erro.

Próxima aula

No próximo artigo vamos usar o Illuminate Database para conectar no banco de dados e já listarmos algo na tela antes de configurar o Slim!


Cursos relacionados


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