terça-feira, 27 de junho de 2017

Criando cache para as rotas no slim

Sabe quando você esta desenvolvendo sua aplicação, e você percebe que uma determinada rota recebe um monte de requisições sempre com o mesmo parâmetro, aquele momento em que seu webservice recebe um monte de requisições pra retornar a lista de produtos da empresa, que praticamente nunca muda?

É nessas horas que você precisa pensar em cache ( tá o exemplo pode não ser dos melhores, mas você entendeu tenho certeza..rs).

Configurar cache no slim é muito fácil. nas configurações da aplicação, basta setar um nome válido na propriedade routerCacheFile. Da uma olhadinha abaixo como fica:


$config = [
    'settings' => [
        'addContentLengthHeader' => false,
        'displayErrorDetails' => true, // set to false in production
        'routerCacheFile' => __DIR__ . '/../routes.cache.php',
    ],
];
 
$app = new Slim\App($config);

É importante lembrar que todo este cache não tem nenhum controle hein, então pra renovar o cache o mesmo terá de ser apagado (obvio que você pode criar um mecanismo para isso né :)). No artigo que estou usando como base para transcrever este exemplo aqui, tem um exemplo que cria as rotas, e as armazena, com um pequeno teste de performance:


 [
        'addContentLengthHeader' => false,
        'displayErrorDetails' => true, // set to false in production
        'routerCacheFile' => __DIR__ . '/../routes.cache.php',
    ],
];
 
$app = new Slim\App($config);
 
for ($groupName = 1; $groupName <= 25; $groupName++) {
    $app->group("/$groupName", function() {
        for ($i = 1; $i <= 1000; $i++) {
            $this->get("/$i/{id:\d+}", App\Action::class);
            $this->post("/$i/{id:\d+}", App\Action::class);
            $this->put("/$i/{id:\d+}", App\Action::class);
            $this->delete("/$i/{id:\d+}", App\Action::class);
        }
    });
}
 
// Run!
$start = microtime(true);
$app->run();
$diff = microtime(true) - $start;
echo "\n" . sprintf("%0.03f", $diff * 1000);

O que ele esta fazendo, é criar as rotas dinamicamente. Faça um teste acesse uma rota 2 vezes, vai ser notávle o o ganho de performance. Depois venho escrever um artigo usando o http_cache no slim, mostrando como criar rotas com datas de validade :). POST original: https://akrabat.com/slims-route-cache-file/

sexta-feira, 18 de novembro de 2016

Phinx - Migration pra todo mundo (inclusive pra quem usa slim)





Quem me conhece sabe que eu não sou fan do Laravel, na verdade meu problema é ser fan do Slim, e acaba que eu prefiro buscar soluções pra implementar no slim as coisas legais que vejo em outros frameworks, e se tem uma coisa legal no Laravel são os migrations.


Migration é realmente um recurso muito útil, durante a evolução do projeto, e nessa vontade de usar no slim, acabei encontrando uma ferramenta, meio que por acaso, o  Phinx, que tem um rep no github (https://github.com/robmorgan/phinx).


Pra quem já usou no Laravel, é basicamente a mesma coisa, e pra quem nunca usou, recomendo fortemente que de uma olhadinha no manual, vai ver como  é simples e fácil de usar.



quarta-feira, 19 de outubro de 2016

Enquete: Microframework PHP

Bom dia.

Eu estava procurando novidades sobre microframeworks, e achei esta pesquisa:

https://www.slant.co/topics/2642/~php-microframeworks

Quem estiver usando algum microframework, poderia votar lá, pra ajudar a entender bem esse mercado. Eu sendo bem honesto tive no slim um excelente parceiro no desenvolvimento, então acabou que tirando o Silex, não olhei outros microframeworks.

terça-feira, 18 de outubro de 2016

MysqlDBDoc e urls com parametros opcionais

Bom dia..

Eu estou envolvido em um projeto bem grande com uma base de dados gigantesca e precisava de uma maneira de documentar um banco de dados Mysql, procurei uma ferramenta e não achei nenhuma que fosse simples o suficiente pra eu usar.

Criei um scriptzinho bem simples, e estou usando ele, fiz em slim, pra acelerar o processo:


https://github.com/jonasthomaz/mysqldbdoc

Hoje ele só esta fazendo o basíco (documentando). Preciso adicionar a busca, e ja fica bem funcional. se alguem quiser dar uma fuçada lá, fica a vontade.

Uma das coisas que eu queria dizer aqui é em relação a um recurso muito legal do slim, que é a definição de urls, com parametros opcionais:

Eu criei uma estrutura pra ir entrando no db: conexao > schema > tabela > field, e para isso precisei criar apenas uma url, e tratei tudo numa chamada só:


$app->get('/read(/:schema(/:table(/:field)))',function($schema = '', $table = '', $field='') use ($app){
// aqui entra o código
});

O interessante nessa estrutura é que é realmente muito fácil, você só precisa adicionar o parenteses e a definição da variavel, e pronto tem a urlzinha customizada :).




Ah! quanto ao projeto, quem quiser colaborar, dar palpites, criticar, fiquem a vontade.

terça-feira, 31 de maio de 2016

Slim Framework - Passo a Passo.

Foi adicionado recentemente um tutorial para quem esta começando (e pra quem já esta acostumado a desenvolver) no Slim.

É muito bom ver que o framework continua sua evolução, eu voltei a trabalhar com PHP diretamente, então estou entusiasmado em poder voltar a blogar, e aproveitando vou deixar aqui o link pro Tutorial.

Ele cobre tudo o que você precisa para começar, desde a instalação e configuração, lidar com bancos de dados e de log, rotas, views etc. Assim que eu tiver um tempinho, vou ver se traduzo o conteúdo e coloco aqui.

http://www.slimframework.com/docs/tutorial/first-app.html

O tutorial foi produzido por: Lorna Mitchell

segunda-feira, 23 de março de 2015

Entendendo o Middleware

Na semana passada, dia 17/03 pra ser mais exato, foi feito um post no twitter oficial  do Slim, pedindo que quem tem middlewares prontos para o slim v3.x, que postassem,  então, como eu estou vendo hoje a lista vazia, resolvi escrever um postzinho sobre o que são esses middlewares, e como eles funcionam no slim.

Vamos lá, antes de mais nada, é importante dizer os middlewares só são possiveis pela implementação do Rack, que é uma arquitetura pipeline muito usada em frameworks Ruby. Com esta arquitetura você consegue acessar, analisar e modificar o ambiente da sua aplicação. Além de muito elegante é realmente muito funcional.


Entendendo o Middleware

Uma aplicação no slim é a união de várias camadas, e cada camada dessa, é um middleware.
Existe uma ilustração, muito conhecida de quem desenvolve em slim, que esta em qualquer artigo sobre middleware:
Essa ilustração, considera que você esta utilizando cache em sua aplicação.
Nessa ilustração, a página(ou o conteúdo que você busca),  esta no centro, logo fica claro, que até que você tenha o seu conteúdo gerado, passaremos por todas as camadas anteriores. Essas camadas vnao dizer se prosseguimos na execução ou se desviamos para qq outro lugar.
Quanto a ilustração:
1 - É verificada a autenticação do usuário, se não estiver autenticado o fluxo será interrompido e geramos um erro (401);
2 - Verificamos depois se existe cache da página que esta sendo criada, se sim, mostramos o cache, e interrompemos o fluxo;
3 - Criamos o conteúdo da página solicitada e exibimos.

Bem simples né, da pra entender bem o funcionamento. Quando você cria o seu próprio middleware, ele se tornará uma nova camada desta aplicação, acima de todas as outras existentes.


Implementando o seu middleware

O objetivo do middleware é inspecionar, analisar ou modificar o ambiente de aplicação, solicitação e resposta antes e / ou após que a aplicação Slim é invocada. Dentro do middlware, você pode obter referências para a aplicação facilmente:

<?php
class MeuMiddleware extends \Slim\Middleware
{
    public function call()
    {
        //Acesso a aplicação
        $app = $this->app;

        //Acesso Ao ambiente
        $env = $app->environment;

        //Acesso ao objeto request
        $req = $app->request;

        //Acesso ao objeto response
        $res = $app->response;
    }
}

O que for alterado ao ambiente, request e response serão imediatamente propagadas para todo o ambiente da sua aplicação, uma vez que o objeto da aplicação (nosso famoso $app) é compartilhado por toda a aplicação.


Além das referências a aplicação propriamente dita, o middleware tem uma referência a cada inferior a aplicação, através do método $this->next->call(), Assim é possível encerrar seu ciclo de vida explicitamente.

<?php
class MeuMiddleware extends \Slim\Middleware
{
    public function call()
    {
        //Chama o próximo middleware
        $this->next->call();
    }
}

Na documentação do slim, temos um exemplo bem simples de um middleware, que vai deixar toda a saída em maiúsculo.

<?php
class AllCapsMiddleware extends \Slim\Middleware
{
    public function call()
    {
        // Pegamos a referencia a aplicação aqui
        $app = $this->app;

        // Chamamos o proximo middleware
        $this->next->call();

        // Aqui tornamos toda a resposta maiúscula
        $res = $app->response;
        $body = $res->getBody();
        $res->setBody(strtoupper($body));
    }
}

Para adicionar sua classe middleware á sua aplicação:

<?php
$app = new \Slim\Slim();
$app->add(new \AllCapsMiddleware());
$app->get('/foo', function () use ($app) {
    echo "Hello";
});
$app->run();


Quando eu vi esta funcionalidade, a primeira coisa na qual eu pensei foi em um middleware para autenticação, acho que todo mundo pensa..rs, mas muita coisa pode ser feita,  mesmo a implementação em cache, CSRF, e por ai vai...

Pra finalizar esse assunto, venho em breve falar sobre os hooks.


Abraços a todos ai.






terça-feira, 17 de março de 2015

Usando o Slim no GAE

Então eu estava pensando aqui em uma maneira de começar a implementar um projetinho de testes, e vou unir 2 coisas  que tenho usado muito ultimamente: o Slim e o GAE.

Todo mundo deve conhecer o Google App Engine, então não vou explicar nada da ferramenta, se você queiser tirar alguma dúvida, acessa a documentaçnao https://cloud.google.com/appengine/docs que com certeza vai esclarecer muito mais do que eu poderia aqui no blog, sem contar que não é este o nosso objetivo.


Configurando o ambiente

Antes de mais nada eu criei uma aplicação no GAE, e você pode acessar ela através do link: http://myslimerp.appspot.com/, eu pretendo utilizar esta app de exemplo pra todos os testes e demonstrações aqui do blog tá...

1 - Vamos colocar o slim framework na nossa aplicação (vou usar o composer pq é bem mais fácil né :), se você ainda não usa composer, segue ai como instalar ó o link é de ambiente mac, que é o que eu uso, mas pra windows não deve ser muito diferente ).  Então logo após eu ter clonado minha app do GAE, eu ja usei o composer no diretório da minha app pra instalar nosso amigão.


composer require slim/slim


2 - Agora vamos configurar nosso app.yaml, para definir o index.php como o nosso handler padrão.

application: id-da-sua-aplicacao-aqui
version: 1
runtime: php
api_version: 1

handlers:
# ...
- url: /.*
  script: public_html/index.php



3 - Bora criar nosso index.php, e já criar nossa primeira rota pra receber as requisições:
<?php
require 'vendor/autoload.php';

$app = new \Slim\Slim();

// Google App Engine não define a $_SERVER['PATH_INFO']
$app->environment['PATH_INFO'] = $_SERVER['REQUEST_URI'];

$app->get('/', function () {
    echo "Uhuuu o Slim esta vivo !!!";
});

$app->run();

Prontinho, nosso slim já esta rodando no GAE.
Agora já podemos começar a codar nossa aplicação utilizando o GAE, que ótimo né :)...

Até a próxima, e fico ai no aguardo por sugestões de temas para os próximos posts. Ah! e eu não esqueci da série sobre os protocolos HTTP que havia prometido nos posts anteriores. Vou dar continuidade neles sim.

Abraços

Slim 2.6.0 e voltando a blogar


Boa tarde povo, foi liberada a versão nova do slim, a 2.6.0, e esta é a minha desculpa pra voltar a blogar depois deste tempo parado, já que eu comecei a blogger e acabei parando.

Bom, sobre a versão nova tem como principal característica uma correção na classe SessionCookie. Ela corrige uma vulnerabilidade que permitia injections na mesma, e por esse motivo a atualização é altamente recomendada.

Vou começar a blogar de acordo com um projeto no qual estou trabalhando neste momento e postando de acordo com as dificuldades que tiver, e conforme forem surgindo novidades no framework eu vou postando aqui..




terça-feira, 10 de junho de 2014

O Protocolo HTTP


Um dos objetivos deste blog é me auxiliar no processo de aprendizado do Slim, e um recurso que realmente me atrai no slim é a maneira como ele trata as rotas, é um mecanismo bem simples de se implementar, se tornando uma ferramenta bem poderosa quando você o compreende.

Todo desenvolvedor web sabe como funciona o protocolo HTTP (ou pelo menos deveria saber). Então vamos a uma pequena introdução sobre ele para tentar cobrir os aspectos que nos interessam.

Um pouquinho da história

Hypertext Transfer Protocol (HTTP) é o método utilizado para enviar e receber informações na internet.  O protocolo é definido pela especificação RFC 2616 ( da versão 1.1). Vamos ser sinceros, é grande, é uma leitura massante, são informações estruturais como esta que vão fazer a diferença entre um usador de scripts e um desenvolvedor de verdade.


Como funciona?

O protocolo HTTP é baseado em requisições e respostas entre clientes e servidores. O cliente — navegador ou dispositivo que fará a requisição; também é conhecido como user agent — solicita um determinado recurso (resource), enviando um pacote de informações contendo alguns cabeçalhos (headers) a um URI ou, mais especificamente, URL. O servidor recebe estas informações e envia uma resposta, que pode ser um recurso ou um simplesmente um outro cabeçalho.

Eu fiz uma solicitação aqui pro meu blog, usando o Google Chrome, abaixo esta a chamada que foi feita ao servidor web:

  1. 1 GET / HTTP/1.1 2 Host: slimframework.blogspot.com.br 3 Connection: keep-alive 4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 5 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 6 Accept-Encoding: gzip,deflate,sdch 7 Accept-Language: en-US,en;q=0.8,pt;q=0.6,gl;q=0.4 8 If-None-Match: "de5a18d4-97e2-4cf2-a045-52c8dbb41f93" 9 If-Modified-Since: Tue, 10 Jun 2014 11:57:08 GMT

Vamos analizar o cabeçalho:

- As linhas 1 e 2 mostra o tipo de solicitação que foi realizada, o método GET, e a versão do http que estamos utilizando (no caso a 1.1), e o a url requisitada;
- A linha 4 mostra quais os formatos de retorno aceitáveis pelo agente (no meu caso o agente é o Google Chrome em um Mac OS exibido na linha 5);


Agora um exemplo de como obter um array com estas informações no slim:
 <?php  
 $app = new \Slim\Slim();   
 $app->get('/',function () use ($app){  
      $headers = $app->request->headers;  
      print_r($headers);  
 });  
 $app->run();  

De posse destas informações você pode realizar os tratamentos necessários, e as customizações necessárias para o output de seu código.


O cabeçalho da resposta a solicitação GET é o seguinte:
  1. HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Expires: Tue, 10 Jun 2014 13:14:24 GMT Date: Tue, 10 Jun 2014 13:14:24 GMT Cache-Control: private, max-age=0 Last-Modified: Tue, 10 Jun 2014 13:13:04 GMT ETag: "df47e326-bd55-46e6-af5f-e44883753dc2" Content-Encoding: gzip X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Length: 24379 Server: GSE Alternate-Protocol: 80:quic

Reparem o código 200 de status logo na primeira linha (conheça todos os códigos de status clicando aqui), seguida das informações do conteúdo (utilizadas na renderização pelo brownser, e que você poderia utilizar no seu cliente) na segunda linha.

Compreender o cabeçalho permitirá a você extender muito suas aplicações, especialmente quando estiver construindo um serviço REST, no momento de criar autenticações, chaves personalizadas, retornos especificos,  etc.

O protocolo HTTP é stateless, ou seja, ele não é capaz por si só de reter informações entre requisições diferentes.  Ou seja(2) cada requisição que é feita ao servidor web é uma nova requisição, e ela não armazena as informações da requisição anterior.
Para persistir informações você utilizar cookies, sessões, campos de formulário ou variáveis na própria URL.

Pra deixar isso mais claro pra você como os cookies funcionam : quando você usa a instrução PHP pra criar um cookie, ele é gerado no agente e depois disso em todas as solicitações ele será incluído no cabeçalho http , permitindo que você trabalhe com esta informação.


Status

Toda requisição recebe um código de resposta conhecido como status. Com o status é possível saber se uma operação foi realizada com sucesso (200), se ele foi movida e agora existe em outro lugar (301) ou se não existe mais (404).

Existem muitos status divididos em diversas categorias. Na especificação você pode ver cada um deles com uma descrição bastante detalhada.  Se você quiser ver todos os códigos clique aqui.

Vou adicionais aqui, os que você provavelmente usará no desenvolvimento da sua aplicação:

Cod. Nome Descrição
200 OK Indica que uma requisição foi feita com sucesso.
201 Created Indica que uma requisição foi feita com sucesso e que um recurso foi criado. Normalmente utilizamos esse padrão de resposta para POST e PUT.
400 Bad Request Infica que uma requisição não possuí um formato especifico. Normalmente utilizada quando alguma validação de dados não passa, ou quando esta faltando algum dado ou até mesmo um formato errado. Muito comum utilizar como erro de retorno para POST e PUT.
401 Unauthorized Indica que o recurso ou endpoint precisa de um requisição autenticada antes de proseguir.
404 Not Found Indica que o recurso da requisição não existe. Normalmente utilizado quando um endpoint não corresponde com nenhuma rota registrada na aplicação.
405 Method Not Allowed Indica que o método HTTP utilizado não esta disponível para aquele endpoint.
409 Conflict Indica que um conflito ocorreu durante a requisição. Por exemplo, isso poderia ocorrer quando você utiliza PUT para atualizar o mesmo registro com dados duplicado, pode não ser um exemplo muito bom, mas não tenho nada melhor em mente.
422 Unprocessable Entity Indica que a request foi realizada e entendida pelo servidor, porem não foi possível proceguir devido a erros no formato/parâmetros informados. Por exemplo, o erro pode ser lançado caso você espere um XML como parâmetro mas ao invés disso o cliente envia um JSON, ou em um caso mais simplificado poreriam ser valores obrigatórios em um JSON que não correspondem com um modelo/validação.
500 Internal Server Error Indica uma falha do lado servidor, normalmente utilizamos quando algo inesperado acontece do lado servidor.

Pra finalizar

Bom é isso, eu ainda não falei dos VERBOS, mas eu vou deixar para um próximo post, pois vou abordar os verbos e a maneira como implementar cada um deles no slim.






O porque?


O Slim é um framework que tem como objetivo ajudar o desenvolvedor a criar de modo rápido aplicações web e apis.


Os Recursos do framework:
  • Um tratamento poderoso de rotas
    • Permite a utilização de métodos HTTP padrão (put, get, post e delete) e personalizados
    • Parâmetros de rota com wildcards e condicionais
    • Rotas com redirecionamento, parada, e passagem
    • Middleware para tratamento de rotas
  • Renderização de templates com views customizadas
  • Utilização de Flash messages
  • Cookie seguro com criptografia AES-256
  • Permite construção com cache HTTP
  • Registro de Logs com scripts personalizados
  • Tratamento de erros e depuração
  • Middleware e hooks
  • Configuração simples

A instalação é muito simples, você pode usar o composer, ou baixar o pacote do framework (ridiculamente pequeno) no site, veja aqui como instalar.

A partir do próximo post, vou fazer uma revisão sobre um aspecto muito importante para desenvolvedores web, e mostrando como tirar proveito com o o Slim, o Protocólo HTTP e seus métodos. Abraços.