Em 25 de abril de 2019, a nova versão alpha
principal do microframework Slim viu a luz do dia e, em 18 de maio, passou a beta
. Sugiro que você se familiarize com a nova versão.
Sob o corte:
- Sobre as inovações da estrutura
- Escrevendo um aplicativo simples no Slim-4
- Sobre a Amizade Slim e PhpStorm
Novo no Slim 4
Principais inovações em comparação com a versão 3:
- A versão mínima do PHP é 7.1;
- Suporte para PSR-15 (Middleware);
- Removida a implementação de mensagens http. Instale qualquer biblioteca compatível com PSR-7 e use;
- Removida a dependência do Pimple . Instale seu recipiente compatível com PSR-11 favorito e use-o;
- A capacidade de usar seu roteador (anteriormente, não era possível abandonar o FastRoute );
- Mudou a implementação do tratamento de erros;
- Implementação alterada da saída da resposta;
- Fábrica adicionada para criar uma instância do aplicativo;
- Configurações removidas;
- O Slim não define mais
default_mimetype
como uma string vazia; portanto, você precisa instalá-lo no php.ini
ou no aplicativo usando ini_set('default_mimetype', '')
; - O manipulador de solicitação de aplicativo agora aceita apenas o objeto de solicitação (na versão antiga, aceitava objetos de solicitação e resposta).
Como criar um aplicativo agora?
Na terceira versão, a criação do aplicativo era mais ou menos assim:
<?php use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Slim\App; require 'vendor/autoload.php'; $settings = [ 'addContentLengthHeader' => false, ]; $app = new App(['settings' => $settings]); $app->get('/hello/{name}', function (ServerRequestInterface $request, ResponseInterface $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name"); return $response; }); $app->run();
Agora o construtor do aplicativo aceita os seguintes parâmetros:
Agora também você pode usar o método de create
estático da fábrica de aplicativos \Slim\Factory\AppFactory
.
Este método aceita os mesmos parâmetros que a entrada, apenas todos eles são opcionais.
<?php use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Slim\Factory\AppFactory; require 'vendor/autoload.php'; $app = AppFactory::create(); $app->get('/hello/{name}', function (ServerRequestInterface $request, ResponseInterface $response) { $name = $request->getAttribute('name'); $response->getBody()->write("Hello, $name"); return $response; }); $app->run();
Devolva-me 404 erros!
Se tentarmos abrir uma página inexistente, obteremos um código de resposta 500
, não 404
. Para que os erros sejam processados corretamente, você precisa conectar \Slim\Middleware\ErrorMiddleware
<?php use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Slim\Factory\AppFactory; use Slim\Middleware\ErrorMiddleware; require 'vendor/autoload.php'; $app = AppFactory::create(); $middleware = new ErrorMiddleware( $app->getCallableResolver(), $app->getResponseFactory(), false, false, false ); $app->add($middleware); $app->get('/hello/{name}', function (ServerRequestInterface $request, ResponseInterface $response) { $name = $request->getAttribute('name'); $response->getBody()->write("Hello, $name"); return $response; }); $app->run();
Middleware
O middleware agora deve ser uma implementação do PSR-15. Como exceção, você pode transmitir funções, mas a assinatura deve corresponder ao método process()
da \Psr\Http\Server\MiddlewareInterface
<?php use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\RequestHandlerInterface; use Slim\Factory\AppFactory; require 'vendor/autoload.php'; $app = AppFactory::create(); $app->add(function (ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $response = $handler->handle($request); return $response->withHeader('Content-Type', 'application/json'); });
A assinatura ($request, $response, $next)
não ($request, $response, $next)
mais suportada
Como viver sem configurações?
Você pode viver sem configurações. As ferramentas fornecidas nos ajudarão com isso.
httpVersion
e responseChunkSize
A httpVersion
foi responsável pela saída da versão do protocolo na resposta.
A configuração responseChunkSize
determinou o tamanho de cada pedaço lido do corpo da resposta quando enviado ao navegador.
Agora, essas funções podem ser atribuídas ao emissor da resposta.
Escrever emissor
<?php
Nós nos conectamos ao aplicativo
<?php use App\ResponseEmitter; use Slim\Factory\AppFactory; require 'vendor/autoload.php'; $app = AppFactory::create(); $serverRequestFactory = \Slim\Factory\ServerRequestCreatorFactory::create(); $request = $serverRequestFactory->createServerRequestFromGlobals();
outputBuffering
Essa configuração permitiu ativar / desativar o buffer de saída. Definir valores:
false
buffer false
está desativado (todas as chamadas para echo
, print
instruções de print
são ignoradas).'append'
- todas as chamadas para echo
, instruções de print
são adicionadas após o corpo da resposta'prepend'
- todas as chamadas para echo
, instruções de print
são adicionadas antes do corpo da resposta
\Slim\Middleware\OutputBufferingMiddleware
desenvolvedores de \Slim\Middleware\OutputBufferingMiddleware
propõem a substituição dessa opção pelo \Slim\Middleware\OutputBufferingMiddleware
, no construtor do qual é transmitida uma fábrica de fluxo compatível com PSR-17 e um modo que pode ser igual a append
ou append
<?php use Slim\Factory\AppFactory; use Slim\Factory\Psr17\SlimPsr17Factory; use Slim\Middleware\OutputBufferingMiddleware; require 'vendor/autoload.php'; $app = AppFactory::create(); $middleware = new OutputBufferingMiddleware(SlimPsr17Factory::getStreamFactory(), OutputBufferingMiddleware::APPEND); $app->add($middleware);
determineRouteBeforeAppMiddleware
Essa configuração tornou possível obter a rota atual do objeto de solicitação no middleware
É fornecida uma substituição \Slim\Middleware\RoutingMiddleware
<?php use Slim\Factory\AppFactory; use Slim\Middleware\RoutingMiddleware; require 'vendor/autoload.php'; $app = AppFactory::create(); $middleware = new RoutingMiddleware($app->getRouteResolver()); $app->add($middleware);
displayErrorDetails
A configuração permitiu exibir detalhes do erro. Ao depurar, facilita a vida.
Lembre-se de \Slim\Middleware\ErrorMiddleware
? Aqui nos ajudará!
<?php use Slim\Factory\AppFactory; use Slim\Middleware\ErrorMiddleware; require 'vendor/autoload.php'; $app = AppFactory::create(); $middleware = new ErrorMiddleware( $app->getCallableResolver(), $app->getResponseFactory(), true,
addContentLengthHeader
Essa configuração permitiu ativar / desativar a adição automática do cabeçalho Content-Length
com o valor do volume de dados no corpo da resposta
Substitui a opção de middleware \Slim\Middleware\ContentLengthMiddleware
<?php use Slim\Factory\AppFactory; use Slim\Middleware\ContentLengthMiddleware; require 'vendor/autoload.php'; $app = AppFactory::create(); $middleware = new ContentLengthMiddleware(); $app->add($middleware);
routerCacheFile
Agora você pode instalar diretamente o arquivo de cache do roteador
<?php use Slim\Factory\AppFactory; require 'vendor/autoload.php'; $app = AppFactory::create(); $app->getRouteCollector()->setCacheFile('/path/to/cache/router.php');
Criando um aplicativo no Slim-4
Para dar uma olhada mais de perto na estrutura, escreveremos um pequeno aplicativo.
O aplicativo terá as seguintes rotas:
/hello/{name}
- página de boas-vindas;/
- redirecionar para a página /hello/world
- Outras rotas retornarão uma página personalizada com erros 404.
A lógica estará nos controladores, renderizaremos a página através do mecanismo de modelo Twig
Como bônus, adicione um aplicativo de console baseado no componente Symfony Console com um comando que exibe uma lista de rotas
Etapa 0. Instalando Dependências
Vamos precisar de:
Selecionei ultra-lite / container como o container de dependência, como leve, conciso e compatível com o padrão.
Os desenvolvedores PSR-7 e PSR-17 Slim fornecem slim / psr7 em um pacote. Vamos usá-lo
Supõe-se que o gerenciador de pacotes do Composer já esteja instalado.
Criamos uma pasta para o projeto ( /path/to/project
será usado como exemplo) e vamos para ele.
Adicione o arquivo composer.json
ao projeto com o seguinte conteúdo:
{ "require": { "php": ">=7.1", "slim/slim": "4.0.0-beta", "slim/psr7": "~0.3", "ultra-lite/container": "^6.2", "symfony/console": "^4.2", "twig/twig": "^2.10" }, "autoload": { "psr-4": { "App\\": "app" } } }
e execute o comando
composer install
Agora temos todos os pacotes necessários e o carregador automático de classes está configurado.
Se trabalharmos com o git , adicione o arquivo .gitignore
e o diretório do vendor
(e o diretório do seu IDE, se necessário)
/.idea/* /vendor/*
Estou usando o PhpStorm IDE e orgulhoso disso . Para um desenvolvimento confortável, é hora de fazer amizade com o contêiner e o IDE.
Na raiz do projeto, crie o arquivo .phpstorm.meta.php
e escreva este código:
<?php
Esse código informa ao IDE que, para um objeto que implementa a \Psr\Container\ContainerInterface
, o método get()
retornará um objeto de classe ou implementação de interface cujo nome é passado no parâmetro
Etapa 1. Estrutura do Aplicativo
Adicione os diretórios:
app
- código do aplicativo. Vamos conectar nosso namespace para o carregador automático de classes a ele;bin
- diretório para o utilitário do console;config
- aqui serão os arquivos de configuração do aplicativo;public
- um diretório aberto na web (ponto de entrada do aplicativo, estilos, js, imagens etc.);- diretório
template
- template
; var
é o diretório para vários arquivos. Logs, cache, armazenamento local, etc.
E os arquivos:
config/app.ini
- a principal configuração do aplicativo;config/app.local.ini
- configuração para ambiente local
;app/Support/CommandMap.php
- mapeamento de comandos de aplicativos de console para carregamento lento.app/Support/Config.php
- Classe de configuração (para que o IDE saiba quais configurações temos).app/Support/NotFoundHandler.php
- classe de manipulador de erros 404.app/Support/ServiceProviderInterface.php
- A interface do provedor de serviços.app/Provider/AppProvider.php
- O principal provedor do aplicativo.bootstrap.php
- montagem de contêiner;bin/console
- ponto de entrada do aplicativo de console;public/index.php
- ponto de entrada do aplicativo da web.
config / app.ini ; slim.debug=Off ; templates.dir=template ; templates.cache=var/cache/template
config / app.local.ini ; . ; slim.debug=On ; templates.cache=
Sim, ainda é bom excluir configurações de ambiente do repositório. Afinal, pode haver aparências / senhas. O cache também é excluído.
.gitignore /.idea/* /config/* /vendor/* /var/cache/* !/config/app.ini !/var/cache/.gitkeep
app / Support / CommandMap.php app / Suporte / Config.php app / Suporte / NotFoundHandler.php Agora você pode ensinar o PhpStorm a entender quais teclas possuem chaves e que tipo elas são.
app / Support / ServiceProviderInterface.php app / Provider / AppProvider.php Movemos o roteamento para o contêiner para podermos trabalhar com ele sem inicializar o objeto \Slim\App
.
É aconselhável dar permissão a este arquivo para executar
chmod +x ./bin/console
Verificação
Inicie o aplicativo de console:
./bin/console
Em resposta, a janela de boas-vindas do componente symfony/console
deve aparecer com dois comandos disponíveis - help
e list
.
Console Tool Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug Available commands: help Displays help for a command list Lists commands
Agora inicie o servidor web.
php -S localhost:8080 -t public public/index.php
E abra qualquer URL no localhost: 8080.
Todas as solicitações devem retornar uma resposta com o código 404
e um corpo vazio.
Isso acontece porque não temos rotas listadas.
Resta conectar o render, escrever modelos, controladores e definir rotas.
Etapa 2. Renderizar
Adicione o modelo template/layout.twig
. Este é o modelo básico para todas as páginas.
template / layout.twig {# template/layout.twig #} <!DOCTYPE html> <html lang="en"> <head> <title>{% block title %}Slim demo{% endblock %}</title> </head> <body> {% block content %}{% endblock %} </body> </html>
Adicione um template/hello.twig
página de boas-vindas template/hello.twig
template / hello.twig {# template/hello.twig #} {% extends 'layout.twig' %} {% block title %}Slim demo::hello, {{ name }}{% endblock %} {% block content %} <h1>Welcome!</h1> <p>Hello, {{ name }}!</p> {% endblock %}
E o template/err404.twig
página de erro template/err404.twig
template / err404.twig {# template/err404.twig #} {% extends 'layout.twig' %} {% block title %}Slim demo::not found{% endblock %} {% block content %} <h1>Error!</h1> <p>Page not found =(</p> {% endblock %}
Adicione o app/Provider/RenderProvider.php
provedor de renderização app/Provider/RenderProvider.php
app / Provider / RenderProvider.php Ligue o provedor no bootstrap
Adicionar uma renderização ao manipulador de erros 404
app / Support / NotFoundHandler.php (DIFF) app / Provider / AppProvider.php (DIFF) 404 .
3.
2:
app/Controller/HomeController.php
—app/Controller/HelloController.php
—
( URL ), — ( html)
app/Controller/HomeController.php app/Controller/HelloController.php ,
app/Provider/WebProvider.php - ( )...
php -S localhost:8080 -t public public/index.php
… http://localhost:8080 , http://localhost:8080/hello/world
world'.
http://localhost:8080/hello/ivan ivan'.
, , http://localhost:8080/helo/world 404 .
4.
route:list
app/Command/RouteListCommand.php ,
app/Provider/CommandProvider.php ...
./bin/console route:list
… :
Routes ====== --------------- --------- ------- ------------------------------------- Route Methods Name Handler --------------- --------- ------- ------------------------------------- / GET index App\Controller\HomeController:index /hello/{name} GET hello App\Controller\HelloController:show --------------- --------- ------- -------------------------------------
, , !
, Slim — routes.php
( ), . — , , .