Posts da Tag: Laravel - Blog da TreinaWeb

PHP

O que é Lumen?

Assim como o Slim e o Flask, o Lumen é um micro-framework desenvolvido por Taylor Otwell (que também é desenvolvedor do Laravel), lançado em abril de 2015 sobre a licença MIT, escrito em PHP e hospedado no GitHub.

PHP - Fundamentos
Curso de PHP - Fundamentos
CONHEÇA O CURSO

Relembrando Micro-Framework…

Um Micro-Framework são Frameworks modularizados que possuem uma estrutura inicial muito mais simples quando comparado a um Framework convencional.

Pense em um Micro-Framework como uma peça de lego. Inicialmente, um projeto criado com o micro-framework possui apenas o básico para funcionar, (normalmente, sistema de rotas). Porém, ao decorrer do projeto, podem haver necessidades para utilização de outros recursos como, conexão de banco de dados, sistemas de templates, envio de email, etc. A partir desta necessidade, novas bibliotecas são “encaixadas” no projeto, como uma estrutura de lego.

Exemplificando Micro-Framework

De volta ao Lumen

Caracterizado como um dos Micro-Frameworks mais rápidos existentes atualmente, o Lumen é uma excelente opção na criação de APIs REST e no desenvolvimento de aplicações de microsserviços.

Derivado do Laravel, o Lumen possui uma menor quantidade de recursos nativos quando comparado ao “seu irmão mais velho”. Porém, por permitir que novos recursos de terceiros possam ser adicionados através do Composer e permitir habilitar os componentes nativos do Laravel como o próprio Eloquent ORM, o mesmo torna-se uma excelente opção para o desenvolvimento de vários tipos de projetos.

Características do Lumen

Assim como a maioria dos Micro-Frameworks, o Lumen tem como principal característica a sua simplicidade, mas esta não é a única, como podemos ver abaixo:

  • Por possuir apenas o necessário para o desenvolvimento, a simplicidade do Lumen é um ponto positivo para sua utilização. Deste modo, torna-se mais simples que comparado a frameworks maiores já que sua arquitetura é muito mais simples;
  • Possui maior rapidez no desenvolvimento já que o desenvolvedor irá se preocupar apenas com o necessário para o seu projeto. Desta forma, anula configurações desnecessárias para a aplicação;
  • Diante da sua arquitetura mais simplista, tendem a ser menores e mais leves quando comparado a outros frameworks;
  • Permite também a criação de aplicações mais robustas. Por ser um micro-framework totalmente personalizável, permitindo assim, caso necessário, a criação de uma arquitetura mais definida, entre outros.
Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Exemplo de uma aplicação Lumen

Abaixo podemos verificar um exemplo de uma aplicação Lumen, e notar a sua simplicidade:

<?php

$app->get('user/{id}', function($id) {
    return User::findOrFail($id);
});

Basicamente, a aplicação acima recebe uma requisição do tipo GET para a rota “/user/{id}” e retornar o usuário que possui o id enviado como parâmetro.

Podemos concluir que…

Como vimos durante todo o artigo, o Lumen é uma excelente escolha para o desenvolvimento de APIs REST e microsserviços, já que sua estrutura mais simples permite focar apenas no necessário e utilizar os recursos essenciais para sua criação.

No site do Lumen podemos verificar toda sua documentação, comunidade e tudo sobre a ferramenta.


Desenvolvimento Back-end

Camadas e componentes do padrão arquitetural Porto

O padrão arquitetural Porto possui algumas camadas para tratar cada parte da aplicação. Nesse post vamos conhecer um pouco mais sobre cada uma dessas camadas e também sobre os componentes que podem compor a camada de containers.

Caso ainda não conheça o padrão arquitetural Porto, vale a leitura do artigo onde explicamos: O que é o padrão Porto e como ele funciona.
PHP - Orientação a Objetos - Parte 1
Curso de PHP - Orientação a Objetos - Parte 1
CONHEÇA O CURSO

Camadas do padrão Porto

O padrão arquitetural Porto é composto por 2 camadas principais Ship (navio) e Containers. Conforme ilustra o diagrama abaixo:

diagrama que mostra as 3 camadas do padrão arquitetural porto

Existe também uma terceira camada mais conceitual chamada Sea (oceano), que podemos considerar como sendo os recursos de baixo nível que usamos na aplicação, como frameworks e bibliotecas, conforme mostrado acima.

Camada Ship

A camada Ship (navio) é a camada intermediária da nossa aplicação. Ela faz a ligação entre o código de baixo nível da camada Sea (oceano) e a camada de alto nível Containers.

Na parte de interação com o baixo nível que são os frameworks, bibliotecas e outras APIs de baixo nível da linguagem. A camada de Ship possui recursos, como bootstrap necessário para a aplicação, arquivos de configuração, registro de serviços e outros detalhes específicos.

Ela abriga também classes genéricas que são usadas dentro dos containers, como exceções, middlewares, classes de integração com serviços específicos, configurações compartilhadas e outros.

A camada de Ship ainda conta com classes de base. Essas classes podem ser estendidas dentro da camada Containers e permitem compartilhar código entre os diversos containers da aplicação.

Camada de containers

A camada de containers possui o código de alto nível da aplicação. Ela interage com a camada de nível intermediário (Ship).

Ela é responsável pela implementação da regra de negócio da aplicação. A ideia é que cada container contenha uma parte da regra de negócio. Ele deve receber a requisição e responder de acordo com cada UI (User Interface), que pode ser uma API, aplicação clássica web ou outra interface.

O ideal é que cada container esteja ligado a somente uma entidade/model da aplicação, mas nada impede que ele possua mais de um, porém quanto maior a quantidade de models, maior a complexidade do container, algo que o padrão estrutural tenta ao máximo evitar. Quanto mais simples os containers, maior a possibilidade de reutilizá-lo.

Componentes dos containers no padrão arquitetural Porto

Os containers são formados por componentes, cada um com sua responsabilidade. Eles podem ser componentes obrigatórios e opcionais.

O diagrama abaixo mostra como os componentes interagem dentro de um container:

Componentes da camada de containers da parquitetura porto

Os componentes pontilhados são opcionais enquanto os com linha contínua são obrigatórios. Note que temos os mesmos componentes do padrão MVC, veremos abaixo a responsabilidade deles no Porto.

Responsabilidade dos componentes no padrão arquitetural porto

Responsabilidade dos principais componentes:

  • Route – É o componente responsável por definir para cada caminho acessado qual será o controller responsável;
  • Controller – Recebe os dados da requisição, realiza a validação e autorização (em classe separada), envia para processamento em uma action e devolve a resposta apropriada;
  • Request – É o componente que obtém os dados de input da requisição. Pode também validar os dados e fazer autorização a partir deles. Deve sempre ser chamada a partir do controller;
  • Action – É responsável por receber os dados do controller, processar e devolver a ele. Ela está diretamente ligada a uma regra de negócio específica, se estivermos usando diagrama de caso de uso, podemos dizer que uma action é responsável por um caso de uso específico;
  • Task – Componente onde podemos colocar pequenas regras de negócio e que serão chamadas por diferentes actions do mesmo container ou de outros para evitar duplicidade;
  • Model – Usado para representar a estrutura no banco de dados. Ele não deve conter regras de negócio, apenas elementos referente ao mapeamento das tabelas e relacionamentos do banco de dados;
  • View – Elemento usado para separar o HTML da lógica da aplicação. Usada somente para UI (User Interface) web;
  • Transformers – Responsável por preparar os dados de saída quando trabalhamos com retornos para API. Sua principal vantagem é desacoplar o modo como os dados são retornados pelos modelos, permitindo a API retorna-los conforme sua necessidade;
  • Exceptions – Classes de exceções personalizadas, usadas para especificar as exceções que acontecem dentro do container;
  • Sub-Actions – Possui basicamente a mesma função das actions, porém é usada para eliminar duplicação de código. Ao invés repetir o mesmo código em duas Actions, usamos uma sub-action.

Existe também os componentes opcionais que podem ser usados conforme a necessidade do projeto.

Estrutura de pastas de container no padrão Porto

Abaixo é possível ver a estrutura de pastas de um container usando os principais componentes que conhecemos:

Container
    ├── Actions
    ├── Tasks
    ├── Models
    ├── Exceptions
    ├── Tests
    │   ├── Unit
    │   └── Traits
    └── UI
        ├── API
        │   ├── Routes
        │   ├── Controllers
        │   ├── Requests
        │   ├── Transformers
        │   └── Tests
        │       └── Functional
        ├── WEB
        │   ├── Routes
        │   ├── Controllers
        │   ├── Requests
        │   ├── Views
        │   └── Tests
        │       └── Acceptance
        └── CLI
            ├── Routes
            ├── Commands
            └── Tests
                └── Functional

Seções de containers

Os containers podem ser agrupados em seções. O principal objetivo delas é separar os containers de acordo com o contexto.

Cada seção de containers pode representar uma parte do seu sistema, o arquiteto tem a liberdade de escolher como criar as sessões e quais containers estarão dentro dela de acordo com sua aplicação.

Desenvolvedor Django Full-Stack
Formação: Desenvolvedor Django Full-Stack
Aprenda nesta formação como desenvolver aplicações complexas utilizando o Django, principal framework para desenvolvimento web de todo o ecossistema Python. Para isso, você verá desde os conceitos mais básicos, até conceitos mais avançados.
CONHEÇA A FORMAÇÃO

Considerações finais

O padrão arquitetural Porto faz uso de vários conceitos que já são utilizados normalmente em aplicações back-end, o que facilita aos desenvolvedores compreenderem o que cada componente faz e também garante algumas características já comprovadas ao utilizar esses conceitos.

Você pode ler a documentação completa sobre o padrão Porto no seu repositório do Github.


Desenvolvimento Back-end

Conheça o padrão arquitetural Porto para aplicações back-end

Nesse post vamos conhecer o padrão arquitetural Porto. Voltado principalmente para aplicações back-end, ele usa conceitos de diversos outros padrões para definir um padrão modular, com baixo acoplamento e altamente testável.

Python - Orientação a objetos
Curso de Python - Orientação a objetos
CONHEÇA O CURSO

O Que é Porto?

O Porto é um padrão arquitetural criado por Mahmoud Zalt. Seu principal objetivo é ajudar os desenvolvedores a criarem aplicações de médio e grande porte de forma manutenível e reutilizável.

Ele utiliza conceito de outros padrões já largamente usados e conhecidos, como DDD (Domain Driven Design), Modular, Micro Kernel, MVC (Model View Controller), Layered e ADR (Action Domain Responder). O Porto também se utiliza de uma série de princípios, como SOLID, programação orientada a objetos, LIFT, DRY (Don’t repeat yourself), CoC (Convention over configuration), GRASP (General Responsibility Assignment Software Patterns), generalização, alta coesão e baixo acoplamento.

Ele foi criado pensando nos principais problemas do desenvolvimento web back-end, porém pode ser utilizado também em outros tipos de aplicação. Uma das suas principais vantagens é que ele permite a criação de aplicações monolíticas de forma organizada e caso necessário ainda facilita a divisão em micro serviços, graças ao modo como é estruturado.

Como funciona o padrão arquitetural Porto?

O padrão arquitetural Porto pode ser usado independente de tecnologia e está baseado em duas camadas principais, Ship (navio) e Containers. Ele ainda considera uma terceira camada que chama Sea (oceano) que basicamente consiste no código de baixo nível, como, frameworks e bibliotecas que nossa aplicação interage.

Abaixo podemos ver uma imagem ilustrando as camadas:

imagem que mostra as camadas do padrão arquitetural Porto (ship, containers e sea)

A camada Ship (navio) é a camada intermediária da nossa aplicação. Ela faz a ligação entre o código de baixo nível da camada Sea (oceano) e a camada de alto nível Containers. Sua responsabilidade principal é interagir com recursos do framework e bibliotecas, além de possuir elementos base para a camada de containers.

A camada de containers possui o código de alto nível da aplicação. Ela interage com a camada de nível intermediário (Ship). Sua responsabilidade é cuidar das regras de negócio do projeto.

O problema das múltiplas interfaces

O desenvolvimento de aplicações que possuem múltiplas UI User Interface (interface de usuário) é uma realidade no mercado. Na maioria dos casos, as aplicações são desenvolvidas para no mínimo duas UI. A interface web e a interface para dispositivos móveis, através de aplicativos específicos para Android e IOS.

Baseado nesse cenário as aplicações back-end precisam servir a diferentes aplicações. Isso pode ser um grande problema, uma vez que por mais que as interfaces de usuário tenham na maioria dos casos os mesmos requisitos, existem situações onde os requisitos são diferentes. Essa situação pode causar um gargalo no projeto, já que temos várias equipes de aplicações front-end solicitando desenvolvimento de novos recursos.

O problema descrito acima, pode ser tratado de diversos modos, como utilizando o padrão back-ends for front-ends, onde temos um back-end para cada interface de usuário ou até mesmo usando diferentes API gateway quando estamos usando micro-serviços.

O padrão arquitetural Porto como uma alternativa

As abordagens levantadas acima são interessantes, porém elas trazem um custo a mais para o projeto, manter diferentes back-ends para diferentes front-ends pode ser muito custoso. E a abordagem de micro-serviços não se aplica a qualquer tipo de projeto, uma vez que existe um ganho significante de complexidade de controle dos serviços em relação a uma aplicação monolítica.

O padrão arquitetural Porto trás características que nos ajuda no cenário descrito acima. Ele é estruturado de forma a permitir que a aplicação back-end possa responder a diferentes interfaces de usuário usando as mesmas regras de negócio. Ele também permite que a aplicação seja estruturada inicialmente como monolito que pode ser migrado, caso necessário, com o crescimento da aplicação para o modelo de micro-serviços.

Por que conhecer o padrão estrutural Porto?

O padrão arquitetural Porto é importante como uma nova proposta para o mercado, uma vez que ele tenta atacar gaps que outros padrões conhecidos possuem.

O modo como ele foi estruturado, garante uma série de atributos de qualidade ao projeto. Elementos como modularidade dão ao padrão uma característica bem interessante, a possibilidade de transformar uma aplicação monolítica em micro serviços, algo extremamente difícil nos padrões amplamente utilizados no mercado

Devido a sua filosofia de responsabilidade única, classes pequenas e padrões bem definidos de entradas e saída. O padrão Porto permite a criação de aplicações altamente testáveis e manuteníveis.

Outro aspecto muito interessante, é o fato da regra de negócio da aplicação estar desacoplado da UI (User Interface). Desse modo é possível que uma aplicação utilize a mesma lógica para responder diferentes tipos de aplicações. Por exemplo, uma API, uma aplicação web e uma aplicação console.

Padrão arquitetural Porto na comunidade

A tendência é de acordo com que mais pessoas conheçam o padrão, ele ganhe espaço no mercado, uma vez que é possível implementá-lo na maioria das tecnologias usadas para desenvolvimento de aplicações back-end.

A comunidade de desenvolvimento de software está sempre aberta a novos padrões como é o caso do Porto, porém como é algo normal em tecnologia, é necessário um tempo de maturação até que as empresas comecem adotar em produtos reais.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

Considerações finais

Atualmente o Porto ainda é uma padrão arquitetural que está mais presente na comunidade PHP, mais especificamente na comunidade Laravel, uma vez que seu criador faz parte dessa comunidade e também mantém uma implementação do padrão sobre o Laravel chamado Apiato.

Apesar de estruturado sobre diversos outros padrões e componentes conhecidos do mercado, o Porto ainda não foi implementado largamente. Isso faz com que não seja possível comprovar de maneira prática seus atributos de qualidade.


PHP

Symfony Componentes: o que são e qual sua importância para o ecossistema PHP

Recentemente apresentei uma palestra no PHP Community Summit falando sobre o Ecossistema Symfony, que você pode assistir no final deste artigo. A principal motivação para o conteúdo dessa palestra e também deste post é a importância que o Symfony possui para o ecossistema macro do PHP como um todo. Muito desta relevância do Symfony vem dos seus componentes, então vamos falar um pouco sobre eles.

O que são os componentes Symfony

A maioria das pessoas quando ouve falar a palavra Symfony logo pensa em um framework PHP. Na verdade, o Symfony é bem mais que isso, veja a definição oficial do site do Symfony:

O Symfony é um conjunto de componentes, um framework, uma filosofia e uma comunidade.

Antes mesmo de falar que Symfony é um framework existe uma ênfase nos componentes, mas o que são esses componentes. Se formos olhar novamente na definição oficial, mas agora sobre os componentes, teremos:

Componentes são pacotes reutilizáveis e desacoplados com objetivos específicos e que podem ser utilizados em qualquer aplicação PHP.

Exatamente nesse ponto entra a importância do Symfony para o PHP. Os componentes não estão acoplados e funcionam exclusivamente dentro do Symfony Framework, é possível usar os componentes em qualquer aplicação PHP.

Symfony - Fundamentos
Curso de Symfony - Fundamentos
CONHEÇA O CURSO

Quem utiliza os componentes do Symfony?

A maioria dos grandes projetos escritos em PHP utilizam algum dos diversos componentes do Symfony. Veja uma lista abaixo dos principais:

  • Laravel Framework
  • Drupal
  • Magento
  • Joomla
  • Yii Framework
  • API Platform
  • SDK PHP do facebook
  • SDK PHP do Google
  • PHPStan
  • Behat
  • Composer

A lista é muito grande! Na página do Symfony é possível verificar os projetos e quais componentes cada um utiliza. Uma coisa é certa, basicamente qualquer projeto PHP que vamos trabalhar utiliza algum tipo de componente do Symfony.

Porque tanta gente utiliza os componentes do Symfony

Nesse ponto deve estar se perguntando o que esses componentes fazem de especial para serem utilizados em tantos projetos importantes na linguagem PHP e aqui entram dois pontos bem importantes.

O primeiro ponto que leva muitos projetos a utilizarem os componentes do Symfony é a confiabilidade. Os componentes são testados e utilizados em milhares de projetos, além de possuírem uma comunidade por trás que realiza manutenções de segurança e melhorias regularmente.

O segundo ponto é a produtividade, ao invés de reinventar a roda e correr o risco que ela não fique tão redonda quanto o necessário, o que acaba sendo menos produtivo e mais arriscado, porque não utilizar a roda que já está pronta e testada.

O que esses componentes fazem

O Symfony possui componentes para diversos tipos de ações. Existem componentes que ajudam na estruturação de uma aplicação, por exemplo a estruturação de um framework. Existem componentes que ajudam em tarefas comuns a maioria das aplicações, por exemplo enviar email. E também existem componentes que são Polyfill para extensões e versões do PHP, por exemplo, vamos supor que sua aplicação necessite do PHP 7.3, porém não pode instalar essa versão em seu servidor, nesse caso pode instalar um componente que entregará as funções da versão sem realmente possuir.

Alguns exemplos de componentes para estruturação de uma aplicação:

  • HTTP Kernel – Responsável por ajudar na estruturação desde o processo de request até o retorno da Response;
  • HTTP Foundation – Permite acesso a uma implementação orientada a objetos do protocolo HTTP;
  • Routing – Facilita o trabalho de roteamento da aplicação;
  • DependencyInjection – Implementa o container e recursos de injeção de dependência
  • Config – Facilita o acesso às configurações;
  • Dotenv – Permite o acesso às variáveis de ambiente;

Alguns componentes que realizam tarefas comuns a maioria das aplicações:

  • Mailer – Envio de email usando diversos serviços de forma extremamente simples;
  • HTTP Client – Permite realizar requisições HTTP a outras aplicações;
  • Form – Facilita a criação e a recuperação dos dados enviados via formulário;
  • Validation – Permite a validação de dados usando regras predefinidas ou através da criação de novas regras;
  • Security – Facilita o trabalho de autenticação e autorização na aplicação;
  • Cache – Facilita a utilização de cache com diversos meios de armazenamento;
  • DomCrawler – Possui mecanismos que permite navegar em documentos HTML e XML.

Temos também os componentes de polyfill:

  • Polyfill PHP 5.4 até 7.3
  • Polyfill XML
  • Polyfill Intl
  • Polyfill Mbstring
  • Polyfill Ctype

Sempre que for usar componentes de polyfill é necessário consultar a documentação para verificar quais funções o componente realmente implementa, pois nem todas podem estar disponíveis.

Porque não utilizar os componentes do Symfony

Nem tudo são rosas, como a maioria das coisas também existem pontos negativos ao usar componentes prontos.

Podemos citar primeiramente a falta de liberdade. Se sua aplicação necessita de uma nova função que não possui no componente. Caso queira implementar no componente oficial terá que convencer a equipe mantenedora que sua nova funcionalidade é importante para a maioria das pessoas que utilizam o componente, além de ter que seguir todas as regras para contribuir no projeto.

Outro ponto é a dependência do componente. A aplicação pode ficar dependente de um componente de tal forma que se ele for descontinuado ela esteja em risco. Por outro lado, isso pode ser contornado com a arquitetura correta da sua aplicação, se ao invés de depender diretamente do componente, depender de contratos, será possível trocar de componente com o mínimo de esforço.

Conclusão

O Symfony possui mais de 50 componentes para os mais diversos propósitos. Aconselho acessar a lista de componentes e ler o que cada um deles realiza. Desse modo sempre que tiver uma situação onde é necessário implementar uma nova funcionalidade na sua aplicação, poderá considerar um componente Symfony analisando as vantagens e desvantagens discutidas aqui.

Desenvolvedor Symfony Full-Stack
Formação: Desenvolvedor Symfony Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Symfony com desenvoltura. Ao final desta formação, terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso usando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Principais métodos para obtenção de parâmetros da Request no Laravel

Nesse artigo vamos ver como obter os dados enviados pelo usuário no Laravel. Na verdade, quando falamos em pegar dados enviados pelo usuário, seja via formulário ou diretamente na URL, estamos falando da Request. Caso não saiba o que é Request temos esse artigo que fala sobre alguns conceitos HTTP.

O Laravel possui uma classe específica para trabalhar com os dados enviados na requisição. Essa classe tem o nome de Request e fica no namespace \Illuminate\Http. Ela possui uma série de métodos que facilitam obtenção das informações enviadas pelo cliente.

PHP - Novidades dos PHP 7.0 e 7.1
Curso de PHP - Novidades dos PHP 7.0 e 7.1
CONHEÇA O CURSO

Como podemos utilizar a classe Request

Geralmente o local onde mais usamos os dados enviados na requisição é o Controller. No Laravel, podemos injetar instâncias diretamente nos métodos do controller, isso nos permite usar facilmente a instância da classe Request.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function store(Request $request)
    {
        //Usamos a instância para chamar os métodos da requisição
        $request->...();
    }
}

Obtendo dados enviados via URL

O modo mais simples de enviar informações do usuário para o servidor através da requisição é a URL. Usando um padrão específico podemos passar dados no formato chave valor, veja a URL abaixo:

http://servidor.test/meurecurso?escola=Treinaweb&curso=Laravel

Através dela estamos passando os parâmetros escola e curso que possuem respectivamente os valores TreinaWeb e Laravel.

Para obter todos os dados passados na URL usamos o método query sem passar nenhum parâmetro $request-&gt;query(). O Laravel pega todos os parâmetros e retorna em forma de array:

array:2 [
  "escola" => "Treinaweb"
  "curso" => "Laravel"
]

O método query pode ser usado para obter apenas um valor, basta passar o nome da chave no primeiro argumento. Caso a chave não esteja declarada na URL ainda é possível definir um valor padrão no segundo argumento.

$request->query("escola");
$request->query("escola", "Valor padrao");

Montando o formulário de exemplo

Os dados enviados via POST estão localizados no corpo da requisição. O Laravel possui alguns métodos que nos permitem obter essas informações para serem usadas na nossa aplicação.

Para conseguirmos enviar informações via POST precisamos criar um formulário que será submetido para uma rota qualquer da nossa aplicação. Vamos usar como base o seguinte formulário:

<form action="http://servidor.test/meurecurso" method="POST">
    {{ csrf_field() }}
    Nome <input type="text" name="name" value="Elton"> <br>
    Idade <input type="text" name="age" value="27"> <br>
    Email<input type="text" name="email" value="elton.fonseca@treinaweb.com.br"> <br>
    <input type="submit" value="Enviar">
</form>

OBS: o helper csrf_field retorna um input do tipo hidden com o token que confirma que o formulário está sendo realmente enviado pela nossa aplicação.

Obtendo dados enviados via POST

O primeiro método que vamos falar é o all() ele retorna todos os dados em formato de array:

array:3 [
  "name" => "Elton"
  "age" => "27"
  "email" => "elton.fonseca@treinaweb.com.br"
]

Outro método que podemos usar é o input. Ele retorna um único valor e podemos definir um valor padrão como segundo argumento, caso a chave não seja encontrada:

$request->input('name');
$request->input('name', 'Nome padrão');

Temos também os métodos only que busca apenas os parâmetros especificados nele e o método except que trás todos parâmetros, exceto os especificados nele. Podemos passar uma lista de argumentos ou um array:

$request->only('name', 'email');
$request->only(['name', 'email']);
$request->except('age');
$request->except(['age']);

Todas as chamadas acima retornam a mesma informação:

array:2 [
  "name" => "Elton"
  "email" => "elton.fonseca@treinaweb.com.br"
]

Uma observação importante! Todos os métodos que vimos nesse tópico all(), input(), only() e except() pegam valores passados via POST e também via GET na URL, dando preferência para os parâmetros POST quando eles possuem o mesmo nome. Enquanto o query, que vimos no tópico anterior, pega apenas os parâmetros passados via GET.

Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Propriedade dinâmica

O Laravel cria propriedades dinamicamente para os parâmetros enviados na requisição, essas propriedades facilitam o acesso aos dados e torna o código mais limpo.

$request->name;  //Treinaweb
$request->age;   //27
$request->email; //elton.fonseca@treinaweb.com.br

É possível obter dinamicamente os parâmetros enviados via GET e POST.

Helper request

Existem algumas situações onde precisamos usar os dados da requisição em locais onde não temos fácil acesso a instância da requisição, nesses casos podemos usar o helper request. Quando chamamos o helper sem passar nenhum argumento ele retorna uma instância da classe request, a partir dela podemos chamar qualquer método da Request:

request()->all();
request()->input("name");
request()->only("email");
//...

Ainda é possível pegar os dados do parâmetro passando o nome do argumento e o valor padrão, para caso o parâmetro não seja encontrado:

request("name", "Nome padrão");

Verificando o parâmetro

Outra situação comum é precisamos verificar se um parâmetro foi passado na requisição. Para isso usamos o método has(). Ele retorna verdadeiro independente do valor passado, mesmo que o valor seja vazio:

if ($request->has('name')) {
    //
}

Caso precise verificar se o parâmetro foi passado na requisição e não é vazio, podemos usar o método filled():

if ($request->filled('name')) {
    //
}

Obter arquivo e realizar upload

O Laravel possui um método especial chamado file para obter os arquivos. Também é possível usar as propriedades dinâmicas:

$request->file('image');
$request->image;

Esse método retorna uma instância da classe Illuminate\Http\UploadedFile, ela já possui todos os recursos necessários para salvar o arquivo de maneira simples. Podemos simplesmente chamar o método store para salvar o arquivo:

$request->file('image')->store('local');

Conclusão

Nesse post nós vimos os principais métodos para obtenção de parâmetros enviados pelo usuário através da requisição. Além desses dados a requisição ainda possui diversas outras informações que são enviadas pelo cliente da nossa aplicação. A documentação do Laravel possui vários exemplos práticos de como obter esses dados.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

O que é Laravel?

O Laravel é um dos Frameworks PHP mais utilizado no mercado.

Caso você não saiba:

Um framework é um facilitador no desenvolvimento de diversas aplicações e, sem dúvida, sua utilização poupa tempo e custos para quem o utiliza, pois de forma mais básica, é um conjunto de bibliotecas utilizadas para criar uma base onde as aplicações são construídas, um otimizador de recursos. Tem como principal objetivo resolver problemas recorrentes com uma abordagem mais genérica. Ele permite ao desenvolvedor focar nos “problemas” da aplicação, não na arquitetura e configurações.

Aqui no blog também temos um artigo bem legal sobre: Para que serve um Framework?

Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

História do Laravel

Desenvolvido por Taylor B. Otwell, tendo sua primeira versão beta lançada em meados de Junho de 2011, o Laravel é um Framework Open Source sob a licença MIT, criado com o propósito de ser uma alternativa mais avançada do CodeIgniter. Atualmente, se encontra na versão 5.8, tendo seu código-fonte hospedado no GitHub.

Recursos do Laravel

Dentre os diversos recursos do Laravel, podemos citar como principais:

  • Sistema de template (Blade)

O Laravel possui um sistema de template que facilita a criação da camada de visualização de dados (Páginas HTML). Com ele, podemos facilmente criar páginas simples e intuitivas de forma rápida e eficaz. Dentre alguns dos recursos do Blade, se destacam: Herança de layouts, sistema de tags, seções e uso de código PHP nos templates.

Imagem código laravel

  • Módulo de autenticação

O Laravel possui, por padrão, um módulo de autenticação/autorização completo que provê todos os recursos para sua implementação, como: Autenticação de usuários, autorização de usuários, recuperação de senhas, logout, controle de sessão e cadastro de usuários.

Tela modulo de autenticação laravel

Com o Laravel não precisamos criar códigos SQL para manipular ou criar tabelas no Banco de Dados. Todo processo é feito utilizando código PHP que, posteriormente, será convertido em instruções SQL. Implementa o padrão Active Record, onde cada model da aplicação representa uma tabela no banco de dados.

Padrão MVC

O Laravel utiliza o padrão MVC (Model, View e Controller) que, basicamente, funciona da seguinte forma:

  • Model é a camada responsável pela parte lógica da aplicação, ou seja, todos os recursos da sua aplicação (consultas ao BD, validações, notificações, etc), mas ele não sabe quando isso deve ser feito, a camada de model apenas tem o necessário para que tudo aconteça, mas não sabe quando irá executar.

  • View é a camada responsável por exibir dados para o usuário, seja em páginas HTML, JSON, XML, etc. A camada View não possui responsabilidade de saber quando vai exibir os dados, apenas como irá exibi-los.

  • Controller é o famoso “meio-de-campo” da aplicação. Essa é a camada que sabe quem chamar e quando chamar para executar determinada ação.

Basicamente, o MVC funciona da seguinte forma:

Ao receber uma requisição, o Controller solicita ao Model as informações necessárias (que virão do banco de dados), que as obtém e retorna ao Controller. De posse dessas informações, o Controller as envia para a View que irá renderizá-las.

Diagrama MVC

Vantagens em utilizar o Laravel

  • Simples e fácil;
  • Documentação completa;
  • Amplamente utilizado;
  • Comunidade ativa;
  • Gratuito.

Concluindo:

O Laravel é um excelente Framework para desenvolvimento de aplicações web. Neste artigo vimos algumas de suas principais características e funcionalidades, o que o torna uma excelente escolha para a criação dos seus projetos.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Como melhorar o retorno das suas APIs no Laravel com API Resource do Eloquent

Quando estamos construindo uma API, alguns pontos são extremamente importantes para que o cliente consiga consumir corretamente as informações. Um desses pontos é o modo como retornamos dados da nossa API.

Em aplicações web existe uma preocupação muito grande com a aparência e usabilidade na hora de mostrar as informações. Quando estamos trabalhando com APIs nossa preocupação não deve ser diretamente ligada a esses detalhes, porém precisamos cuidar de outras características para que os clientes da nossa API consigam utilizá-la de maneira correta. Um desses cuidados deve ser a estrutura que as informações são retornadas.

Como os dados são transferidos em uma API

Geralmente as APIs são utilizadas para integração entre sistemas diferentes. Esses sistemas podem apresentar arquiteturas completamente distintas, por esse motivo os dados são transferidos para um formato intermediário conhecido tanto pela API quanto pelo cliente. Os formatos mais utilizados são JSON, XML e YAML.

O processo de transformação dos dados para esse formato intermediário normalmente é chamado de serialização. No Laravel temos recursos bem importantes para serialização, aconselho a leitura do artigo onde falamos o que é e como utilizar serialização JSON no Laravel. O grande detalhe é que mesmo com os recursos específicos que a serialização possui ele não permite personalizar totalmente a resposta, nesse ponto entra o API Resource.

Laravel - Eloquent ORM
Curso de Laravel - Eloquent ORM
CONHEÇA O CURSO

O que é API Resource

O API Resource é uma camada extra que usamos na API para transformar os dados que vamos enviar ao cliente. Ela permite que a estrutura de retorno seja totalmente personalizada, isso nos permite formatar os dados na melhor maneira para entregar ao cliente. Além de garantir o desacoplamento com o model, uma vez que podemos definir a estrutura de forma separada.
O conceito da camada de transformação não é exclusividade do Laravel. Inclusive no próprio PHP temos algumas outras bibliotecas que facilitam esse trabalho, uma das mais conhecidas é o Fractal. O API Resource do Laravel facilita bastante a vida quando estamos dentro do Framework, mas também é possível utilizar qualquer outra biblioteca.

Resource

O primeiro conceito que precisamos conhecer é o resource. Ele é uma classe que usamos para transformar um único item de um recurso. Falando assim parece um pouco complicado, mas na prática o que ele faz é pegar um item que precisamos converter e transformar para o formato especificado nele. Vamos imaginar que estamos buscando o produto Iphone X no banco de dados e precisamos devolver ele na API com uma formatação específica, é basicamente isso que o Resource faz.

A classe do resource deve possuir um método chamado toArray, esse método precisa retornar um array com os dados que deseja que o recurso possua após a conversão. O Laravel injeta automaticamente as propriedades do nosso model no resource, isso nos permite acessá-las através do escopo this. Veja o exemplo abaixo:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ProductResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'codigo' => $this->id,
            'nome'   => $this->name,
            'preco'  => $this->price,
        ];
    }
}

Basicamente o que estamos fazendo é pegar os dados vindos do model (id, name e price) e colocando respectivamente nos itens do array (código, nome e preço).

O modo como usamos o resource é extremamente simples, basta passarmos 1 item do model no construtor da classe:

new App\Http\Resources\ProductResource(App\Product::find(10));

A instância acima pode ser retornada diretamente em uma action do controller ou em uma rota que utiliza função anônima.

A classe acima parece não fazer muito sentido olhando à primeira vista, porém ganhamos algumas vantagens imprescindíveis em usar essa camada:

  • Liberdade para definição da estrutura
  • Possibilidade de enviar dados extras, como, relações ou gerados através de outros métodos da aplicação
  • Podemos alterar o nome das propriedades do nosso model sem problemas, pois agora definimos o nome que será retornado ao usuário diretamente na estrutura;
  • O nosso model não está preso a somente um modo de exibição, caso necessário podemos criar várias classes de Resource para o mesmo model.
Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Resource Collection

A classe que vimos acima é usada para conversão de apenas um item do model. É comum, porém, precisamos retornar uma coleção de itens na nossa API. Nesse caso utilizamos o Resource Collection. Ele é muito útil para retornar meta informações sobre o conjunto de dados que estamos retornando.
Nele também usamos o método toArray para montar o retorno da nossa aplicação. E usamos a propriedade collection para retornar as informações da coleção:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ProductCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

O modo de usar é basicamente igual ao Resource, porém precisamos passar um conjunto de informações:

new App\Http\Resources\ProductCollection(App\Product::all());

Os dados buscados no banco serão colocados dentro da chave data do nosso resultado. O Laravel automaticamente utiliza o Resource específico para converter cada item da coleção com base na convenção do nome, com isso terá a estrutura definida tanto para cada item específico da coleção como da estrutura geral de retorno.

Conclusão

O modo como retornamos as informações na nossa API é um dos itens mais importantes. Isso juntamente com o uso correto e semântico HTTP dos verbos na requisição e dos códigos na resposta são os itens onde os desenvolvedores mais pecam e que precisa de atenção no desenvolvimento de APIs. Não deixe também de explorar um pouco a documentação do API Resouce no site do Laravel, ele possui recursos para ajudar com relações, meta informações, personalização da resposta HTTP entre outros.

Já leu nossos artigos sobre o ecossistema Laravel e Eloquent? Veja como usar escopos do Eloquent para construir consultas mais limpas no Laravel, como remover a lógica das views com presenters no Laravel e como aliviar seus controllers com os eventos do Eloquent no Laravel, tudo aqui no blog da Treina Web.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Conhecendo os recursos de serialização JSON do Laravel

Imagina que compramos uma barraca de acampar e ao chegar em casa montamos. Provavelmente não vamos conseguir carregar a barraca montada, por esse motivo desmontamos, transportamos e depois realizamos a montagem novamente. Quando estamos falando de programação em algumas situações precisamos realizar basicamente o mesmo processo. Em ciência da computação geralmente chamamos de serialização o ato de converter uma estrutura de dados para um formato de transporte ou armazenamento que pode ser reconstruído depois.

Quando trabalhamos com desenvolvimento de APIs é comum precisarmos serializar para o formato no qual eles serão transportados. Na maioria dos casos as APIs utilizam o formato JSON, porém pode ser qualquer outro como XML ou YAML.

Ao falarmos de serialização o Laravel possui algumas características que nos ajuda a realizar a serialização de forma automática e recursos que nos permite personalizar os dados na serialização.

Laravel - Desenvolvimento de APIs REST
Curso de Laravel - Desenvolvimento de APIs REST
CONHEÇA O CURSO

Serialização automática no Controller

Alguns frameworks como Symfony esperam que o retorno de um método do controller seja sempre uma instância da classe response, contudo no caso do Laravel isso é um pouco diferente. Quando retornamos qualquer estrutura iterável em um controller automaticamente ele tenta serializar para JSON e enviar na resposta. Inclusive ele indica no cabeçalho da resposta que estamos retornando application/json.

Faça um teste retornando um array simples ou mesmo o resultado de uma busca com Eloquent:

public function action()
{
    return ["Escola" => "Treinaweb Cursos"];
}

Ao acessar terá:

conversão json laravel

Mesma coisa também acontece se retornarmos o resultado de uma consulta no banco de dados com Eloquent:

public function action()
{
    return AppProduct::all();
}

Serialização manual

O Laravel também nos permite serializar os dados manualmente. Basta chamarmos o método toJson em uma collection. Como os models do Eloquent sempre retornam uma collection quando buscamos por mais de um registro, podemos trabalhar do seguinte modo:

$products = AppProduct::all();

$json = $products->toJson();

Um detalhe importante! Quando fazemos a serialização o resultado é uma string simples com uma marcação no formato JSON. No caso acima, se retornarmos a variável $json em um controller o content-type será text/html. O correto então é montar a resposta informando manualmente que estamos retornando um application/json.

Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Escolhendo os dados que não serão serializados

Muitas vezes não podemos retornar todos os dados do nosso model para a resposta. Imagine que o produto tem um campo preço de custo, não é nada legal enviar isso para um revendedor, por exemplo.

Nesses casos podemos declarar um atributo no model informando quais propriedades não devem ser incluídas quando realizarmos a serialização:

<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class Product extends Model
{
    /**
     * Atributos que não serão serializados
     *
     * @var array
     */
    protected $hidden = ['cost'];
}

Se por algum motivo em uma serialização específica quiser usar um dos campos escondidos temos um método específico:

$product->makeVisible('cost')->toJson();

Escolhendo os dados que serão serializados

Ao contrário temos também o atributo que indica apenas os campos que serão usados na serialização:

<?php

namespace App;

use IlluminateDatabaseEloquentModel;

class Product extends Model
{
    /**
     * Atributos que serão serializados
     *
     * @var array
     */
    protected $visible = ['id', 'name', 'price'];
}

Podemos usar um método para esconder as propriedades que estão nessa lista:

return $product->makeHidden('price')->toJson();

Outros recursos

Outros dois recursos podem ajudar muito dependendo da situação. O primeiro nos permite usar um acessor na serialização, basta indicarmos o nome dele no atributo appends do model. Além disso podemos formatar propriedades do tipo data com atributo casts.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Como colocar uma aplicação Laravel em produção e automatizar o processo de deploy

O Laravel é um dos frameworks mais falados da web. Existem milhares de posts na internet ensinando como fazer basicamente tudo, porém, até hoje pouco vi falar sobre uma coisa simples: o que precisamos fazer para colocar uma aplicação de forma correta em produção.

Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Configurando o .env

No arquivo .env colocamos as configurações do ambiente específico que vamos rodar a aplicação. Em ambiente de produção dois itens desse arquivo devem obrigatoriamente ser alterados para a segurança da aplicação:

APP_ENV=production
APP_DEBUG=false

O APP_ENV informa qual o nome do ambiente que estamos executando a aplicação. O aconselhável em produção é definir o valor production. Isso porque o Laravel tem uma serie de proteção quando ele está configurado assim. Veja por exemplo o que acontece se tentarmos rodar as migrations com essa diretiva em produção:

rodar migrations em producao

O APP_DEBUG indica para o Laravel se ele deve mostrar erros no navegador. Exibir informações de erro é extremamente perigoso, um usuário mal intencionado pode obter diversas informações a partir dele. Por esse motivo sempre devemos deixar como false, assim ele mostrará apenas a mensagem informando que aconteceu algo de errado:

Mensagem de erro para o usuário laravel

Se precisar saber quais erros estão acontecendo em produção pode verificar o arquivo de log do Laravel.

Doctrine ORM - Fundamentos
Curso de Doctrine ORM - Fundamentos
CONHEÇA O CURSO

Instalando as dependências

Ao clonar a aplicação para nosso servidor de produção, a primeira coisa que precisamos fazer é executar o composer para baixar as dependências do projeto. Quando estamos em produção podemos passar dois parâmetros extras, veja como fica o comando:

composer install --optimize-autoload --no-dev

–optimize-autoload: gera uma versão das regras do PSR-4/PSR-0 em um arquivo PHP único, evitando que a linguagem tenha que o olhar no sistema de arquivos. Esse arquivo de classmap pode ser facilmente cacheado pelo opcache tornando a obtenção dos caminhos muito mais rápido. Mais detalhes em autoloader-optimization

–no-dev: ignora as dependências exclusivas do ambiente de desenvolvimento

Cacheando os arquivos de configuração

Acessar o arquivo .env toda hora é muito custoso, uma vez que ele é um arquivo de texto e não pode ser cacheado pelo opcache. Baseado nisso, o Laravel possui um comando que copia as configurações dele para um arquivo php único diminuindo assim o custo de acesso. Para isso temos o comando:

php artisan config:cache

Único detalhe que devemos ficar atentos quando executamos esse comando. Como as configurações do arquivo de configuração .env são carregados para o arquivo único, não é aconselhável usar o helper env() do Laravel que pega as configurações do arquivo .env já que ele pode não ser carregado.

Cacheando as rotas

O Laravel possui um comando que serializa todas as rotas da aplicação. Esses dados são passados para um único método em um arquivo cacheado. Isso diminui o tempo de carregamento das rotas da aplicação:

php artisan route:cache

O comando acima só funciona se não houver nenhuma chamada de função anônima nos arquivos de rota. A chamada de funções anônimas no arquivo de rota não é uma boa prática por padrão, o cache de rotas é mais um motivo para não usarmos.

Outro processos

Essas são alguma práticas que podemos adotar na hora de realizar o deploy da nossa aplicação. Muitas outras podem ser aplicadas no seu deploy, como, rodar o Laravel Mix ou algum outro automatizador de tarefas, executar testes e outros detalhes.

Veja abaixo de forma prática alguns modos de automatizar os processos mostrados nesse post:

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Como se usa e o que resolve o recurso de Route Model Binding do Laravel

O Route Model Binding não é um recurso novo no Laravel, porém, o pessoal que está começando no framework costuma ter dificuldade em entender qual problema ele resolve e como ele funciona.

Ele existe desde a versão 4.2 do Laravel e de lá para cá já passou por algumas pequenas mudanças e da versão 5.2 em diante não teve mais o modo de usar alterado, com isso podemos chegar à conclusão de que ele alcançou uma boa maturidade.

Laravel - Desenvolvimento de APIs REST
Curso de Laravel - Desenvolvimento de APIs REST
CONHEÇA O CURSO

Qual problema o Route Model Binding tenta resolver?

Antes de falarmos o que é o recurso, é importante sabermos qual problema ele resolve. É muito comum em aplicações web recebermos a partir da URL o código de um registro que vamos precisar realizar uma ação no banco de dados. Veja abaixo alguns exemplos:

http://meusistema.dev/produto/1/mostrar
http://meusistema.dev/produto/1/editar
http://meusistema.dev/produto/1/atualizar
http://meusistema.dev/produto/1/deletar

No caso acima o número 1 representa o código do produto que desejamos realizar determinada ação. Pensando no nosso código, dentro de cada uma dessas ações precisaremos buscar o registro com código 1 no banco de dados. Mas, e se baseado nesse código o próprio framework já buscasse esse registro no banco de dados e injetasse ele prontinho para ser usado, evitando a repetição de código desnecessário? É exatamente isso que o Route Model Binding faz!

Como o Laravel faz isso?

O Laravel faz isso usando o parâmetro na rota e um model do Eloquent. Veja a explicação baseado no nome do recurso:

  • Route: utiliza o nome do parâmetro especificado na rota para saber qual recursos ele deve usar;
  • Model: utiliza o model injetado na ação para realizar a busca baseado no valor passado na rota;
  • Bind: faz o bind entre o parâmetro passado na rota e a variável injetada na ação.

Esse processo por padrão é feito implicitamente, basta passar o nome do parâmetro, o model que será usado e o nome da variável que receberá a instância do model. Existem situações onde não é possível fazer isso de forma automática, pois o valor passado na URL precisa ser filtrado de um modo diferente e não baseado na chave padrão. Nesse caso podemos fazer esse filtro explicitamente.

Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Implicit Binding

No modo implícito o próprio Laravel faz todo trabalho automaticamente, entregando a instância do model já corretamente populada. Se o valor passado na URL não for encontrado no banco de dados, o Laravel retorna um erro de página não encontrada, evitando assim que a execução chegue sequer à ação.

Primeira coisa que precisamos fazer é declarar o parâmetro na rota:

Route::get('products/{product}', 'ProductController@edit');

Agora, na ação do controller, basta injetarmos o model referente ao produto:

/**
 * Show the form for editing the specified resource.
 *
 * @param  AppProduct $product
 * @return IlluminateHttpResponse
 */
public function edit(Product $product)
{
    //aqui temos o produto já filtrado na variável $product
}

Alguns detalhes importantes para evitar problemas na hora de usar o recurso:

1) O nome do parâmetro passado na rota deve ser o mesmo nome da variável injetada da ação:

//nome do parâmetro product
Route::get('products/{product}', 'ProductController@edit');

//injeção na ação
public function edit(Product $product)

2) Se quiser alterar o nome da variável precisa alterar também o nome do parâmetro e vice-versa;

3) Também deve sempre se atentar se está usando a classe correta do model na injeção do método da ação.

Explicit Binding

Existem situações onde nem tudo segue as regras para realização do bind automático. Nesse caso, podemos informar para o framework como fazer o Route Model Binding manualmente.

Essa lógica pode ser criada dentro do método boot em um service provider qualquer. Veja o exemplo abaixo:

Route::bind('product', function ($value) {
    $id = decode($value); 

    return AppProduct::where('id', $id)->first() ?? abort(404);
});

No exemplo acima estamos usando uma função hipotética chamada decode que decodifica o valor passado na URL para o ID válido do banco de dados. Poderia usar qualquer outra lógica, como filtrar por outro campo e etc.

Veja como fica essa configuração usando o RouteServiceProvider:

<?php

namespace AppProviders;

use IlluminateSupportFacadesRoute;
use IlluminateFoundationSupportProvidersRouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'AppHttpControllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        Route::bind('product', function ($value) {
            $id = decode($value); 

            return AppProduct::where('id', $id)->first() ?? abort(404);
        });
    }

    /**
     * Define the routes for the application.
     *
     * @return void
     */
    public function map()
    {
        $this->mapApiRoutes();

        $this->mapWebRoutes();

        //
    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
             ->middleware('api')
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }
}

Conclusão

Esse é mais um recurso do Laravel que nos ajuda a tornar nosso controllers muito mais limpos, legíveis e fáceis de realizar manutenção. Além de tudo isso, ele permite personalizar totalmente a lógica na hora de filtrar o registro, o que o torna muito flexível.

Caso queira continuar seus estudos em Laravel e Eloquent, temos artigos aqui no blog ensinando a usar escopos do Eloquent para construir consultas mais limpas no Laravel, como remover a lógica das views com presenters no Laravel e como aliviar seus controllers com os eventos do Eloquent no Laravel, confira!

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Usando escopos do Eloquent para construir consultas mais limpas no Laravel

É comum precisarmos por diversas vezes fazer consultas que envolvam o mesmo trecho de código. Pensando nisso, o Eloquent possui os escopos, que permitem aplicar modificadores nas consultas. Esses modificadores podem ser aplicados em dois níveis ao model: local e global.

Laravel - Eloquent ORM
Curso de Laravel - Eloquent ORM
CONHEÇA O CURSO

Escopo local

O escopo local permite criar métodos com modificadores. Esses métodos podem ser aplicados a uma consulta como se fossem métodos próprios do Eloquent.

Vamos supor que em um model chamado Client exista uma coluna limit que indica o limite de compra do cliente. É possível imaginar que diversas vezes no projeto precisaremos buscar clientes que possuam limite maior que 0.

Poderíamos ter como exemplo as seguintes consultas:

1) Buscar por nome dos clientes que possuem limite:

Client::where('limit', '>', 0)->where('name', 'like', $nome)->get();

2) Buscar por cidade dos clients que possuem limite:

Client::where('limit', '>', 0)->where('city', $cidade)->get();

Note que repetimos o mesmo código where('limit', '&gt;', 0) nas duas consultas. Isso pode não ser muito bom pois, caso a regra de negocio mude, será necessário alterar dentro de cada local do projeto.

A criação de um escopo pode resolver o problema acima facilmente. Para criar um novo escopo basta definir um método publico na classe do model, ele deve ter o nome no padrão scopeNomeEscopo e receber um parâmetro que contém a instancia do Builder.

Veja o exemplo de escopo para definir o limite &gt; 0:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Client extends Model
{
    /*
     * Escopo que busca clientes com limite
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeHasLimit($query)
    {
        return $query->where('limit', '>', 0);
    }
}

Agora podemos usar o escopo facilmente na consulta como se fosse um método do próprio Eloquent:

Busca por nome dos clientes que possuem limite:

Client::hasLimit()->where('name', 'like', $nome)->get();

Busca por cidade dos clients que possuem limite:

Client::hasLimit()->where('city', $cidade)->get();

À primeira vista, parece não ter muita diferença, mas já ganhamos na legibilidade da leitura das consultas, quantidade de código digitado e também na definição única do código.

Vamos supor que agora ao invés de 0 o limite deve ser maior que 100 e que precise também sempre ordenar pelo maior limite. Provavelmente você ficaria muito feliz em precisar alterar em apenas um local ao invés de vários, além de ter que ficar olhando cada consulta para conferir se está tudo certo.

Escopo global

O escopo global é muito útil quando necessário aplicar um modificador a todos os registros que forem buscados no model. Ao invés de definirmos em cada consulta os modificadores, ou até mesmo criar escopos locais e aplicar em cada consulta, podemos declarar o escopo global.

Vamos supor devemos mostrar apenas clientes ativos e que eles sejam ordenados pela data de cadastro. Podemos adicionar dois escopos:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Client extends Model
{
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        //filtra apenas por clientes ativos
        static::addGlobalScope('active', function (Builder $builder) {
            $builder->where('active', true);
        });

        //ordena pela data de cadastro
        static::addGlobalScope('created', function (Builder $builder) {
            $builder->orderBy('created_at');
        });
    }
}

Agora, toda vez que consultar os clientes automaticamente esses dois modificadores são aplicados.

Consulta sem utilizar o escopo global

Caso não queira aplicar em uma consulta especifica basta chamar o método withoutGlobalScopes():

Client::withoutGlobalScopes()->get();

Se quiser deixar de aplicar apenas um escopo global especifico, basta passar o nome dele:

Client::withoutGlobalScope('created')->get();

Escopo global usando classe própria

É possível também passar uma classe ao invés de uma função anônima para o método addGlobalScope():

static::addGlobalScope(new \App\Scopes\ActiveScope);

Nesse caso a classe para aplicar a condição de ativo ao cliente fica:

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class ActiveScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('active', true);
    }
}

Conclusão

O uso de escopo nos ajuda na legibilidade das nossas buscas e torna o código menos repetitivo. Se aplicado de maneira correta, ele pode ajudar bastante na qualidade do código e facilitar futuras manutenções.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

Já leu nossos artigos sobre Laravel e Eloquent? Veja como aliviar seus controllers com os eventos do Eloquent no Laravel e como remover a lógica das views com presenters no Laravel, tudo aqui no blog da Treina Web.


PHP

Removendo a lógica das views com presenters no Laravel

Um dos problemas mais clássicos de aplicações que utilizam MVC é a camada de view concentrar lógica ao invés de apenas aspectos relacionados à exibição. Veremos nesse artigo como isso pode ser contornado.

Frameworks como Laravel e Symfony utilizam por padrão template engines como Blade e Twig, respectivamente. Esses template engines possuem o intuito de diminuir a complexidade das views, no entanto, nem mesmo com essa ajuda as views ficam limpas o suficiente. Existem certos tratamentos que acabam sobrecarregando as views e também não é papel do model tratar isso. É nesse ponto que entram os Presenters.

Com intuito de ajudar na solução desses problemas podemos usar essa camada extra nas nossas aplicações. O principal objetivo dela é facilitar e devolver a informação já tratada para a view, diminuindo assim a quantidade de decisões que precisamos tomar dentro de nossas views e eximindo também os models de uma responsabilidade que não é deles.

Silex - Framework PHP
Curso de Silex - Framework PHP
CONHEÇA O CURSO

Escolhendo e instalando um Presenter

Por padrão o Laravel não possui uma camada de Presenter, precisamos instalar via Package. Existem diversos packages que fazem esse processo, alguns mais elaborados e outros mais simples. No caso do nosso exemplo vamos usar o desenvolvido por Jeffrey Way que podemos fazer o download no packagist.org.

Basta executar o comando para o composer adicionar a dependência:

composer require laracasts/presenter

Criando e ligando o Presenter ao Model

A ideia é que cada método trate uma única informação, para mantermos também a classe de presenter organizada. No escopo do presenter é possível acessar as propriedades do model, assim fica mais fácil tratar as informações:

<?php
namespace AppPresenters;

use LaracastsPresenterPresenter;

class ProjectPresenter extends Presenter
{
    public function projectName()
    {
        return $this->id . ' ' . $this->name;
    }

    public function finalDate()
    {
        return $this->final_date->diffForHumans();
    }
}

Estamos criando um método que retorna o nome do projeto com o id e outro que retorna a data final do projeto em um formato mais fácil de ler.

Precisamos indicar o nome do presenter e usar uma trait que possui os métodos do pacote no model. Vamos supor que temos um model chamado Project, ele ficaria assim:

<?php

use AppPresentersProjectPresenter;
use LaracastsPresenterPresentableTrait;
use IlluminateDatabaseEloquentModel;

class Project extends Model
{
    use PresentableTrait;

    protected $presenter = ProjectPresenter::class;
}

Finalmente, agora podemos usar os métodos na view. Basta chamar em uma instancia do model um método chamado present(). Veja o exemplo:

{{ $project->present()->projectName }}

Estamos chamando o método ProjectName do presenter. Assim ele vai imprimir no formato ID Nome do projeto que retornamos no presenter.

Exemplo prático

Vamos imaginar que no model de projetos temos uma propriedade chamada status. Dependendo do status temos que definir a cor do label exibido para o usuário:

  • Status não iniciado: Etiqueta Azul
  • Status no prazo: Etiqueta Verde
  • Status atrasado: Etiqueta Vermelha

Usando as classes do bootstrap poderíamos fazer assim:

<span class="label label-{{ $project->present()->statusLabelColor }}">
    Status aqui
</span>

E no presenter definir a lógica:

<?php
namespace AppPresenters;

use LaracastsPresenterPresenter;

class ProjectPresenter extends Presenter
{
    public function statusLabelColor()
    {
            $labels = [
                'nao-iniciado'  => 'primary',
                'no-prazo'      => 'success',
                'atrasado'      => 'danger'
            ];

            return $labels[$this->status];
    }
}

Isoladamente não parece fazer tanta diferença utilizar os presenters ou não, porém, ao compararmos as views dos projetos que utilizam com os que não utilizam, isso fica muito claro.

O resultado é ainda melhor se o nome dos métodos do presenter forem definidos semanticamente, assim além de remover o código “feio” da view ainda a torna mais fácil de ser lida por humanos.

Está estudando sobre Eloquent? Veja como aliviar seus controllers com os eventos do Eloquent no Laravel e como
usar escopos do Eloquent para construir consultas mais limpas no Laravel, tudo aqui no blog da Treina Web.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

Já leu nossos artigos sobre Eloquent? Veja como aliviar seus controllers com os eventos do Eloquent no Laravel e como usar escopos do Eloquent para construir consultas mais limpas no Laravel, tudo aqui no blog da Treina Web.