Blog
O micro-framework Silex
Silex é um micro-framework intuitivo, conciso e extensível. Construído sobre componentes Symfony2, pode ser usado para criar pequenas e grandes aplicações.
Para instalar o micro-framework, você precisa ter em sua máquina o composer(gerenciador de pacotes) tudo fica mais flexível, não somente para instalar o Silex mas também os Providers, que adicionam funcionalidades ao projeto se necessário. O Silex utiliza o Pimple(DIC) para injeção de dependência, facilitando o uso de bibliotecas de terceiros e deixando bem fácil abstrair o seu código..
Usando o Composer.
Crie um diretório para hospedar seu aplicativo Silex e adicione um arquivo composer.json com a seguinte chamada:
{ "require": { "silex/silex": "~1.3" } }
Caso não tenha o composer, faça o download e execute o comando install, no mesmo diretório do arquivo composer.json
recém criado:
$ curl -sS https://getcomposer.org/installer | php $ php composer.phar install
Seu diretório agora armazena a pasta vendor, iremos chamar em nossa aplicação o arquivo /vendor/autoload.php para que tenhamos todos os recursos do Silex.
Podemos iniciar uma aplicação utilizando apenas um arquivo, se desejar. Tudo o que é necessário para ter acesso ao Framework é incluir o carregador automático para criar recursos e suas rotas.
Crie o arquivo .htaccess e depois uma index.php, tudo no mesmo diretório, e inicie sua primeira Aplicação. Veja!
.htaccess
<IfModule mod_rewrite.c> Options -MultiViews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f #RewriteBase / RewriteRule ^ index.php [QSA,L] </IfModule>
index.php
<?php require_once __DIR__.'/vendor/autoload.php'; $app = new Silex\Application(); //Método GET - uma rota para /ola/{nome} $app->get('/ola/{nome}', function($nome) use ($app) { return 'Olá '.$app->escape($nome); }); $app->run();
Quando a rota corresponde, a função é executada e, em seguida, o valor de retorno é enviado de volta para o cliente. Finalmente, o aplicativo é executado.
Vá para o seu navegador: http://localhost/meudir/ola/Fulano. Veja o resultado. É realmente muito fácil!
Quero deixar um exemplo onde construo duas rotas para listar e inserir dados numa tabela de banco de dados.
O Silex é modular e extensível, como mencionei no início do artigo, aos poucos é possível usar provedores de serviço(Providers), quando necessário e de acordo com o crescimento de sua aplicação.
Neste projeto, quero utilizar o Twig Template para formatação do front-end. Veja como instalar e depois registrar este Provider.
Em seu arquivo composer.json, adicione uma nova chamada de instalação para o Twig:
{ "require":{ "Silex/silex":"~1.3", "twig/twig": "^1.24" } }
Rode o Composer:
$ php composer.phar update
Iremos agora registrar nosso novo Provider, o Twig, com $app->register(), passando os seguintes parâmetros:
... $app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__ ."/frontend",)); ...
Veja que escolhi adicionar os templates no diretório /frontend.
A instalação é básica, faço uso de pelo menos um único Provider para o artigo não ficar longo demais e não irei utilizar outros, então tenha em mente que o artigo é introdutório.
Seguindo adiante, vou utilizar a PDO para conectar ao banco de dados.
Veja:
... //PDO - mysql $data_source_name = "mysql:dbname=consumo;host=localhost;charset=utf8"; try { // data_source_name, login, senha e tratamento de erros $database_handle = new PDO($data_source_name, "login","senha", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING)); } catch (Exception $exc) { $exc->getMessage(); } ...
Lembra da aplicação básica na index.php, com uma rota GET(/ola/{nome}), ela pode ser removida pois iremos utilizar uma nova rota GET(/listar).
Este novo recurso(/listar) será responsável por buscar os dados da tabela estimativa. (
SQL para criar e popular a tabela).
Meu novo recurso(/listar) faz uso da instância PDO($database_handle) e utilizará o Provider(Twig) para renderizar os dados obtidos do banco, exibindo-os em nossa template, que ficarão armazenadas no diretório /frontend:
... $app->get("/listar", function() use($app,$database_handle){ //Utilizando a instância($database_handle) $statement_handle = $database_handle->prepare("SELECT id,aparelho,uso_mes,uso_dia,mensal_kwh FROM estimativa ORDER BY id DESC"); $statement_handle->execute(); $response = $statement_handle->fetchAll(PDO::FETCH_ASSOC); return $app[twig]->render("lista.twig", array('dados' => $response, )); }); $app->run();
Veja que o retorno especifica o Provider(twig), já o método render() recebe parâmetros, o nome do template(lista.twig) para essa rota e um array com os dados.
O recurso que acamos de criar utiliza o método HTTP GET. Se você já criou a base e populou a tabela, faça um teste:
http://localhost/meudir/listar
Agora podemos escrever o segundo recurso que receberá um REQUEST, tratará os dados para inserção e caso contrário a requisição, montará o formulário para entrada de dados.
Será necessário usar o método match(), que corresponde todos os métodos. Vamos criar o segundo recurso(/publicar) que instância PDO($database_handle) e depende de um Request para pegar os dados postados. O Silex utiliza recursos como o HttpKernel(do Symfony2) para requests e responses.
Para que seja possível ter uma instância de requisição em sua aplicação, importe o componente (use Symfony\Component\HttpFoundation\Request;) e passe como parâmetro(Request $request) na função anônima.
Neste simples recurso(/publicar) um condicional verifica se há requisição($request->getContent()) um laço para coletar todos os dados por meio do $request->request->all(), caso contrário colete individualmente como no ex.: $request->request->get('campo_aqui').
Se tudo occorrer como planejado, os dados são inseridos e o método redirect() redireciona para outra rota(/listar), já criada. Se um erro for encontado, nosso tratamento de erro(array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING))) setado na instância da PDO, irá exibir algo.
Não havendo requisição, tudo isso é deixado de lado, não entra no condicional e o recurso então renderiza o template('publicar.twig') que contém o formulário.
Veja:
... //importando use Symfony\Component\HttpFoundation\Request; $app = new Silex\Application(); ... $app->match('/publicar', function(Request $request) use($app, $database_handle){ // if($request->getContent()){ foreach ($request->request->all() as $key => $value) { if($key == "submit") continue; $post[$key] .= $value; } $statement_handle = $database_handle->prepare("INSERT INTO estimativa (aparelho,uso_mes,uso_dia,mensal_kwh) VALUES (:aparelho,:uso_mes,:uso_dia,:mensal_kwh)"); $statement_handle->execute($post); return $app->redirect('listar'); } return $app[twig]->render('publicar.twig'); });
Vamos partir para nossos templates(lista e publicar) com Twig que auxilia no tratamento de dados para a montagem do HTML.
Num exemplo simples dentro do modelo lista.twig, podemos ver o uso moderno de tratamento, num laço o array 'dados', que foi lançado pelo recurso(/listar) da aplicação é percorrido e armazenado cada linha na variável 'info':
{% for info in dados %} {{info.aparelho}} {% endfor %}
Já o modelo publicar.twig, é só montar um formulário que passe todos os campos(aparelho,uso_mes,uso_dia,mensal_kwh) os mesmos nomeados dentro do INSERT, após VALUES (:aparelho,:uso_mes,:uso_dia,:mensal_kwh):
Para montar meu formulário, utilizei um recurso legal tipo uma função. Assim como escrever uma função em PHP para fazer e retornar algo, você pode usar uma macro para gerar alguma saída.
Macros são usados para a geração de marcação que podem variar.
Você pode criar um esqueleto com parâmetros macro.
Crie um arquivo forms.html e adicione:
{% macro input(name, value, type, size, class) %} <input type="{{ type|default('text') }}" name="{{ name }}" id="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" class="{{ class }}" required="required" /> {% endmacro %}
Agora importe o forms.html e adicione uma chama dentro do arquivo publicar.twig
{% import "forms.html" as forms %} {{ forms.input('aparelho',null,null,100,'form-control') }}
Veja o formulário completo:
<form action="publicar" method="POST"> <label for="aparelho">Aparelho:</label> {{ forms.input('aparelho',null,null,100,'form-control') }} <label for="uso_mes">Dias Estimados(Uso/Mês):</label> {{ forms.input('uso_mes',null,null,80,'form-control') }} <label for="uso_dia">Média(Utilização/Dia):</label> {{ forms.input('uso_dia',null,null,50,'form-control') }} <label for="mensal_kwh">Consumo Médio Mensal(KWh):</label> {{ forms.input('mensal_kwh',null,null,50,'form-control') }} {{ forms.input('submit','Publicar','submit',null,'btn btn-default') }} </form>
Dica:
Alguns navegadores não suportam diretamente o uso de outros métodos HTTP, fora os métodos mais utilizados(GET e POST).
Para usar PUT por exemplo, você terá que criar um campo de formulário especial com um nome _method, porém a chamada method do formulário deve ser definido como POST:
<form action="/my/target/route/" method="post"> <!-- ... --> <input type="hidden" id="_method" name="_method" value="PUT" /> </form>
Pronto, nosso simples projeto está configurado, rodando dois recursos e com um único Serviço(Twig). Porém, não deixarei a aplicação assim, mais serviços serão adicionados para enxugar o código e melhorar recursos, no segundo artigo explico como substituir o modo como a conexão ao banco de dados é feita.
Vou comitar, e subir o projeto para o GitHub.
Não esqueça de olhar a documentação: silex.sensiolabs.org
[],s