Você está na página 1de 94

Traduzido do Inglês para o Português - www.onlinedoctranslator.

com

Capítulo 15-Mais sobre validação

{{ Form::hidden('hagu', 'mutu') }}

{{Formulário::open(array(

'URL'

=> 'teste/teste',

'arquivos' => verdadeiro

) ) }}

{{ Form::label('avatar', 'Avatar') }}

{{Formulário::arquivo('avatar') }}

{{Formulário::submit('Enviar') }}

{{Formulário::close() }}

//fim do código

O formulário é bastante simples, com alguns truques incluídos. Mas ele tem como alvo a página de
abertura principal que pode ser alterada para algo como ‘registration.blade.php’ ou qualquer coisa que você
quiser. E por padrão ele usa o verbo de solicitação 'POST'. Agora, como podemos validar este formulário para
que ninguém envie uma solicitação em branco, causando graves problemas para nossa aplicação e
sobrecarregando nosso servidor? Nossa primeira prioridade devem ser os campos do formulário que não
deveriam ter sido deixados em branco. Um usuário deve preencher os formulários. Nosso aplicativo analisaria
esse assunto internamente. Lembre-se, a grandeza do Laravel é que ele geralmente cuida desse mecanismo
de maneira fantástica. Você não precisa se preocupar com isso. Como você pode ver, podemos definir mais
regras para nossos usuários aqui. Por exemplo, em nome de usuário, deve haver algum valor alfanumérico.
Devemos forçar nosso usuário a seguir a regra, caso contrário ela não será mantida. Como já disse, as
possibilidades são infinitas; há muito mais opções. A regra é muito simples. E o Laravel assumirá as
responsabilidades principais, então você não precisa se preocupar com isso.
É mais ou menos assim:

Rota::post('/', function()

$postdata = Entrada::todos();

//vamos lidar com o formulário

});

//fim do código

92
Capítulo 15-Mais sobre validação

E o próximo passo seria bem simples:

Rota::post('/', function()

$postdata = Entrada::todos();

$verificar = array(

'nome de usuário' => 'alfa_num'

);

});

//fim do código

Como você pode ver, definimos que nossos usuários sigam uma regra que diz que você deve fornecer
algum valor alfanumérico. Ok, espero que isso seja suficiente para fornecer uma amostra de como funciona.
Antes de embarcar em uma nova jornada para a validação do Laravel, gostaríamos de ver se poderíamos ter
feito alguma validação por conta própria se não tivéssemos um superpoder como o Laravel! Isso nos ajudará a
esclarecer os conceitos.
Vamos testar quase a mesma forma, tornando-a um pouco mais curta por questões de brevidade.
Temos três arquivos: 'form.php', 'validate.php' e 'action.php'. No primeiro arquivo, 'form.php', o formulário
aparecerá e estará pronto para verificação de dois campos: nome de usuário e e-mail. Forçamos nossos
usuários a obedecer a algumas regras, como não enviar envios em branco, e-mail deve parecer e-mail, etc.

//primeiro a página de visualização do formulário:

<h1>

O Clube Louco ByCycle

</h1>

<h2>

Preencha suas credenciais para o

passeio louco!

</h2>

<form método="POST" action="action.php"

aceitarcharset="UTF8">

93
Capítulo 15-Mais sobre validação

<input name="_token" type="oculto"

valor="EMnZhqPbryk7oVPcrjwxuTrlHto">

<label for="nomedeusuário">Seu nome</label>

<p>

<input name="nome de usuário" type="text" value="Seu nome" id="nome de usuário">

<p>

<label for="email">Seu e-mail</label>

<p>

<input name="email" type="text" value="seu e-mail"

id="e-mail">

<p>

<input type="submit" value="Registrar">

/fim do código

É um formulário de página muito simples onde você está prestes a cadastrar seu nome de usuário
e e-mail. Vamos ver como podemos validá-lo em nossa classe 'validate.php'. O código da classe de
validação é assim:

//código inicia

<?php

/*

* . a classe valida verifica duas coisas no nome do usuário

campo

* 1) o nome do usuário não deve ser deixado em branco

* 2) o nome do usuário deve ter entre 3 a 8 caracteres

* Em segundo lugar, verifica o campo de e-mail

*e-mail deve ter um sinal @

94
Capítulo 15-Mais sobre validação

*/

traço ValidateTrait {

função pública verificada() {

return "Ok, seus dados foram salvos";

função pública desmarcada() {

return "Você não forneceu dados adequados.";

interface ValidarInterface {

função pública make($valor);

classe Validar implementa ValidateInterface {

use ValidateTrait;

público $_valor = array();

função pública make($valor) {

$este>_valor = $valor;

if (strlen($valor) === 0 || strlen($valor)

<3 || strlen($valor) > 8){

retorna falso;

elseif(is_string($valor) && trim($valor)

=== ''){

retorna falso;

95
Capítulo 15-Mais sobre validação

elseif (is_array($valor)) {

retorna falso;

elseif (preg_match("/\@.\/i", $valor)) {

retorna falso;

retorne VERDADEIRO;

//fim do código

A seguir em 'action.php' iremos validar este formdata. O código é assim:

//código inicia

<?php

/*

* formulário de validação

*/

requer 'validar.php';

if ($_POST['_token'] === "EMnZhqPbryk7oVPcrjwxuTrlHto"){

$valor = [$_POST['nomedeusuário'],

$_POST['email']];

$validar = new Validar();

if ($validar>fazer($valor[0]) && $validar

> fazer($valor[1])){

echo $validar>verificado();

96
Capítulo 15-Mais sobre validação

outro {

echo $validate>desmarcado();

outro {

echo 'Seus biscoitos! Volte!';

//fim do código

Passamos um token oculto e o comparamos com nossos dados de formulário para que não possa ser
enviado por alguém de fora. Mas poderia ser escrito de uma maneira melhor. Para resumir, capturamos os
dados diretamente, mas acessar diretamente o array superglobal não é uma boa prática. Isso pode ser feito
assim:

//código inicia

<?php

/*

* formulário de validação

*/

requer 'validar.php';

$token = filter_input(INPUT_POST, '_token',

FILTER_SANITIZE_FULL_SPECIAL_CHARS);

$usuário = filter_input(INPUT_POST, 'nome de usuário',

FILTER_SANITIZE_FULL_SPECIAL_CHARS);

$e-mail = filter_input(INPUT_POST, 'e-mail',

FILTER_SANITIZE_EMAIL);

if ($token === "EMnZhqPbryk7oVPcrjwxuTrlHto"){

97
Capítulo 15-Mais sobre validação

$valor = [$usuário, $e-mail];

$validar = new Validar();

if ($validate>make($value[0]) &&
$validate->make($value[1])){

echo $validate->checked();

outro {

echo $validate>desmarcado();

outro {

echo 'Seus biscoitos! Volte!';

//fim do código

Se as linhas de codificação e a união das coisas são importantes para você, você preferirá delegar
sua tarefa ao Laravel. O criador Taylor Otwell e a equipe do Laravel cuidam de todas as possibilidades e
se mantêm próximos do princípio de que nenhuma pedra deve ser revirada. Assim, tudo vai para o seu
devido lugar e você terá todas as opções possíveis para otimizar sua aplicação. Vamos ao nosso antigo
formulário de bicicleta e ver como podemos validá-lo, obrigando nossos usuários a realizar diversas
tarefas que estão disponíveis no Laravel. Já terminamos aqui antes:

Rota::post('/', function()

$postdata = Entrada::todos();

$verificar = array(

'nome de usuário' => 'alfa_num'

);

});

//fim do código

98
Capítulo 15-Mais sobre validação

Agora sabemos o que isso diz. Mas como podemos validar isso? Existe alguma classe de validação? Sim
existe! Vamos descobrir como ele pode ser usado. Para fazer isso precisamos configurar nosso objeto de
validação que irá verificar se a regra é rigorosamente seguida ou não! O código é assim:

//código inicia

Rota::post('/', function()

//Busca todos os dados da solicitação.

$postdata = Entrada::todos();

// Construa o conjunto de restrições de validação.

$verificar = array(

'nome de usuário' => 'alfa_num'

);

// Criando instância que deve ser passada.

$validatingData = Validador::make($postdata,

$verificar);

});

//fim do código

Este código não está completo, como você adivinhou, pois nossa instância de validação deve passar por
um teste rigoroso. Faremos isso em breve. Esses 'pós-dados' podem ser qualquer coisa, conforme você os
definir de acordo. Não importa. Finalmente, o texto completo do código é assim:

//código inicia

Rota::post('/', function()

//Busca todos os dados da solicitação.

$postdata = Entrada::todos();

// Construa o conjunto de restrições de validação.

99
Capítulo 15-Mais sobre validação

$verificar = array(

'nome de usuário' => 'alfa_num'

);

$validatingData = Validador::make($postdata,

$verificar);

if ($validatingData>passes()) {

// quando passar você pode inserir, atualizar seu //banco de dados. Se não passar, você pode retornar o
redirecionamento para uma página //falha e também retornar 'Os dados foram salvos.'

return Redirecionamento::para('/sucesso');

});

//fim do código

Agora você tem o arsenal principal, e como você dispara a partir dele depende de você.
Obviamente, existem muitas outras opções disponíveis junto com os caracteres alfanuméricos. Neste
formulário, se colocarmos um nome como 'sanjib65' ele passará e os dados serão salvos. Mas em vez de
valores alfabéticos ou numéricos colocamos alguns caracteres estranhos como '@!!&*', ele irá falhar.
Nesse caso, podemos usar nosso código desta forma:

//código inicial

Rota::post('/', function()

//Busca todos os dados da solicitação.

$postdata = Entrada::todos();

// Construa o conjunto de restrições de validação.

$verificar = array(

'nome de usuário' => 'alfa_num'

);

$validatingData = Validador::make($postdata,

100
Capítulo 15-Mais sobre validação

$verificar);

if ($validatingData>fails()) {

// Normalmente faríamos algo com os dados.

return Redirecionamento::para('/falha');

retornar 'Dados salvos.';

});

//fim do código

É bastante simples, portanto nenhuma explicação é necessária. Vamos ver como podemos adicionar
muito mais recursos ao nosso array '$check'. Suponha que queiramos que nosso nome de usuário tenha no
mínimo seis caracteres. O que podemos fazer? Muito simples. Laravel escreve como uma descrição explícita:
min:6. Este 'min:6' pode ser alterado para 'min:4' ou 'min:5' ou qualquer comprimento que você precise
adotar. O código é quase o mesmo, com uma pequena alteração, como você supunha.

//código inicial

Rota::post('/registro', function()

//Busca todos os dados da solicitação.

$postdata = Entrada::todos();

// Construa o conjunto de restrições de validação.

$verificar = array(

'nome de usuário' => 'min:6'

);

$validatingData = Validador::make($postdata, $check);

if ($validatingData>passes()) {

// Normalmente faríamos algo com os dados. return 'Dados foram salvos.';

101
Capítulo 15-Mais sobre validação

return Redirecionamento::para('/sucesso');

});

//fim do código

Em vez de 'alpha_num' você escreve 'min:6' e pronto. Mas espere! Há mais. Suponha que você possa
adicionar os dois recursos ao seu nome de usuário. O que você pode fazer? A maior façanha do Laravel é que
ele torna as coisas tão simples e elegantes que você não consegue imaginar antes de usá-lo como está sendo
renderizado. O código completo é assim:

//código inicial

Rota::post('/registro', function()

//Busca todos os dados da solicitação.

$postdata = Entrada::todos();

// Construa o conjunto de restrições de validação.

$verificar = array(

'nome de usuário' => 'alfa_num|min:6'

);

$validatingData = Validador::make($postdata,

$verificar);

if ($validatingData->passes()) {

// Normalmente faríamos algo com os dados.

return 'Dados foram salvos.';

return Redirecionamento::para('/sucesso');

});

//fim do código

102
Capítulo 15-Mais sobre validação

Agora você já sabe que o Laravel vem com muitas facilidades de validação. E todos os
truques surgiram da classe Validation. Você está livre para verificar na tarefa quais são todos os
métodos que estão sendo usados. Além disso, você pode consultar a documentação que
explica bem as regras, uma após a outra. Aqui estou tentando dar uma ideia do que você pode
fazer com esta classe de validação. Vamos verificar este código novamente:

//código inicial

$validatingData = Validador::make(

array('nome' => 'Sanjib'),

array('nome' => 'obrigatório|min:6')

);

//fim do código

A classe validadora possui um método make que recebe o primeiro argumento como os
dados que devem ser verificados. E o segundo argumento mostra os requisitos. Você pode usar
o caractere 'pipe' ou usar array para separar elementos como este:

//código inicial

$validatingData = Validador::make(

array('nome' => 'Sanjib'),

array('nome' => array('obrigatório', 'min:6'))

);

//fim do código

Você também pode usar vários campos:

//código inicial

$validatingData = Validador::make(

variedade(

'nome' => 'Sanjib',

'senha' => 'minhasenha',

'e-mail' => ' me@sanjib.me '

103
Capítulo 15-Mais sobre validação

),

variedade(

'nome' => 'obrigatório',

'senha' => 'obrigatório|min:8',

'e-mail' => 'obrigatório|e-mail|único:usuários'

);

//fim do código

Você já viu como podemos usar a metodologia de 'aprovação' e 'reprovação' para salvar ou rejeitar dados de
formulário. Também podemos usar o método ‘message’ para obter as mensagens de erro. É muito simples:

//código inicial

$validatingData = Validador::make(

array('nome' => 'Sanjib'),

array('nome' => 'obrigatório|min:6')

);

$validatingData = Validador::make(

variedade(

'nome' => 'Sanjib',

'senha' => 'minhasenha',

'e-mail' => ' me@sanjib.me '

),

variedade(

'nome' => 'obrigatório',

'senha' => 'obrigatório|min:8',

'e-mail' => 'obrigatório|e-mail|único:usuários'

104
Capítulo 15-Mais sobre validação

);

$mensagens = $validador->mensagens();

//fim do código

Existe outra opção para recuperar mensagens de erro através do método ‘failed’.

$failedMessage = $validator>failed();

Ao usar este método, você pode obter todas as regras que falharam e que seu usuário não obedeceu
corretamente ao preencher os dados do formulário. Agora, obviamente, a questão é como podemos recuperar
as mensagens de erro ou regras com falha? Quando você chama o método 'message' em uma instância do
Validator, geralmente aparece um array. Obviamente, você definiu muitos parâmetros como este:

//código inicial

variedade(

'nome' => 'obrigatório',

'senha' => 'obrigatório|min:8',

'e-mail' => 'obrigatório|e-mail|único:usuários'

//fim do código

Agora você pode obter um por um – assim:

echo $mensagens->primeiro('email');

Ou você pode obtê-lo como um todo:

//código inicial
foreach ($mensagens>get('email') as $mensagem)

eco $ mensagem. "<br>";

//fim do código

105
Capítulo 15-Mais sobre validação

Suponha que você tenha um código como este, onde já definiu muitas regras de validação e
deseja capturar todas as mensagens de erro de uma só vez. Como você pode fazer isso?

//código inicial

$validatingData = Validador::make(

array('nome' => 'Sanjib'),

array('nome' => 'obrigatório|min:6')

);

$validatingData = Validador::make(

variedade(

'nome' => 'Sanjib',

'senha' => 'minhasenha',

'e-mail' => ' sanjib12sinha@gmail.com '

),

variedade(

'nome' => 'obrigatório',

'senha' => 'obrigatório|min:8',

'e-mail' => 'obrigatório|e-mail|único:usuários'

);

$errorMessages = $validador->mensagens();

foreach ($errorMessages>all() como $mensagem)

eco $ mensagem. “<br>”;

//fim do código

106
Capítulo 15-Mais sobre validação

Você deseja que suas mensagens de erro estejam bem formatadas? Laravel também pensa sobre isso.
Você pode escrever todo o seu código assim:

//código inicial

$validatingData = Validador::make(

array('nome' => 'Sanjib'),

array('nome' => 'obrigatório|min:6')

);

$validatingData = Validador::make(

variedade(

'nome' => 'Sanjib',

'senha' => 'minhasenha',

'e-mail' => ' me@sanjib.me '

),

variedade(

'nome' => 'obrigatório',

'senha' => 'obrigatório|min:8',

'e-mail' => 'obrigatório|e-mail|único:usuários'

);

$errorMessages = $validador>mensagens();

foreach ($errorMessages->all('<li>:mensagem</li>')

como $ mensagem)

eco $ mensagem. "<br>";

//fim do código

107
Capítulo 15-Mais sobre validação

Como você pode ver, há muitas opções. Taylor e sua equipe pensaram em quase todas as
possibilidades e tentaram apoiá-lo de todas as maneiras possíveis. Agora vamos imaginar um
exemplo mais concreto, onde temos um 'register.blade.php' em nossa pasta 'views'. Temos um
formulário como este:

//código inicial

{{Formulário::open(array('url' => '/')) }}

{{ Form::label('nome de usuário', 'Nome de usuário') }}

{{ Formulário::texto('nome de usuário') }}

{{ Formulário::label('email', 'Endereço de e-mail') }}

{{ Formulário::email('email', ' me@sanjib.me ') }}

{{ Campo de senha. }}

{{ Form::label('senha', 'Senha') }}

{{Formulário::senha('senha') }}

{{ Campo de confirmação de senha. }}

{{ Form::label('password_confirmation', 'Confirmação de senha') }}

{{ Formulário::senha('senha_confirmação') }}

{{Formulário::open(array('url' => '/')) }}

{{ Form::hidden('hagu', 'mutu') }}

{{Formulário::open(array(

'URL'

=> 'teste/teste',

'arquivos' => verdadeiro

) ) }}

{{ Form::label('avatar', 'Avatar') }}

{{Formulário::arquivo('avatar') }}

{{Formulário::submit('Enviar') }}

108
Capítulo 15-Mais sobre validação

{{Formulário::close() }}

//fim do código

Agora em nossa rota podemos escrever algo assim:

//código inicial

Route::get('registrar', function()

return View::make('user.register');

});

Route::post('registrar', function()

$regras = array(...);

$validador = Validador::make(Input::all(),

$regras);

if ($validador->falha())

return Redirecionar::para('registrar')
-> withErrors($validador);

});

//fim do código

Agora, quando as regras de validação falham e mensagens de erro são geradas, a variável $error é
automaticamente definida para a sessão. A forma como o Laravel aborda esse problema é bastante inteligente.
Você não precisa vincular explicitamente as mensagens de erro à sua visualização na rota GET. Laravel cuida
disso. Como isso acontece? O Laravel sempre verifica os erros na sessão e os vincula à visualização. Portanto,
se estiver disponível, em cada solicitação a variável $error estará presente na visualização. Você quer mais
alguma coisa? :) Portanto, verifique se há algum campo como este:

echo $erros->primeiro('email');

109
Capítulo 15-Mais sobre validação

Agora é hora de verificar todas as regras de validação. Existem muitos e você pode obter
a lista completa na documentação. Mas deixe-me pegar alguns deles para que você possa
conhecê-los.

//código inicial

variedade(

'campo' => 'aceito'

);

variedade(

'campo' => 'alfa'

);

variedade(

'campo' => 'url'

);

variedade(

'campo' => 'tamanho:8'

);

variedade(

'campo' => 'alfa_dash'

);

variedade(

'campo' => 'url_ativo'

);

variedade(

'campo' => 'após:16/04/15'

);

110
Capítulo 15-Mais sobre validação

variedade(

'campo' => 'antes:09/02/15'

);

variedade(

'campo' => 'único: usuários, nome de usuário'

);

variedade(

'campo' => 'entre:4,9'

);

variedade(

'campo' => 'mesmo:idade'

);

variedade(

'campo' => 'confirmar'

);

array('campo' => 'data');

array('campo' => 'required_without:age,height');

array( 'campo' => 'required_with:idade,altura');

array( 'campo' => 'required_if:nomedeusuario,sanjib');

array('campo' => 'obrigatório');

array('campo' => 'numérico');

//fim do código

Espero que você procure mais regras de validação na documentação do Laravel. Você
obterá mais e tornará suas regras de validação mais interessantes. Aqui brevemente terei
alguma discussão.

111
Capítulo 15-Mais sobre validação

variedade(

'campo' => 'numérico'

);

Aqui você adivinha corretamente. O campo deve ter um valor numérico. Alguns deles são bem
interessantes, como este:

variedade(

'campo' => 'tamanho:7'

);

Aqui, 'tamanho' significa tudo – valor numérico, string, byte de uma imagem – literalmente tudo.
Como você sabe, o tamanho às vezes é realmente importante para alguém! Não é muito útil?

15.1 Regras Condicionais


Às vezes, em sua matriz de entrada, um campo pode não estar presente, mas você deseja verificá-lo.
O que você pode fazer para isso? Não se preocupe! O Laravel já pensa nisso e já traz algumas
soluções para o seu problema. Para um campo não é um grande problema, pois você pode declarar
sua variável assim:

$validatingData = Validador::make($data, array(

'e-mail' => 'às vezes | obrigatório | e-mail',

));

Mas num cenário complexo é bem diferente, como você presumiu. Suponha que você
esteja operando um site de registro e reserva de hotel onde há mais de um campo para você
validar. Para isso, você precisa verificar as solicitações de salas e número de pessoas
apresentadas pelo seu cliente.
Você pode verificar esta declaração condicional assim:

$validatingData = Validador::make($data, array(

'e-mail' => 'às vezes | obrigatório | e-mail',

'quartos'=>'obrigatório|numérico'

));

112
Capítulo 15-Mais sobre validação

Agora, provavelmente você pode querer perguntar por que mais de um quarto é solicitado. Portanto, no
método 'às vezes' você pode adicionar esse argumento e mantê-lo em seu datatarget de 'entrada' no
fechamento que é passado como terceiro argumento. Existem mais casos e para um exemplo detalhado a
documentação do Laravel será útil. Nesta seção de validação, por último, mas não menos importante, está a
parte de Validação Personalizada. Vejamos como podemos fazer algum progresso nesse sentido.

Você pode passar uma mensagem personalizada como esta:

$suamensagem = array(

'required' => 'O campo :attribute é necessário.',

);

$validador = Validador::make($input, $rules, $suamensagem);

E você pode passar uma série de mensagens, não importa o tamanho que você queira!

15.2 Validação Personalizada


Portanto, a validação não requer muito esforço se você conhece os truques. Acontece que você
precisa conhecer as classes e variáveis definidas por padrão. Mas, além disso, você também pode
criar algumas regras de validação habituais. O Laravel tem uma tremenda capacidade de se expandir
e até mesmo de encorajá-lo a escrever alguns métodos incríveis. Portanto, nunca se sinta abalado e
tente sempre fazer justiça a esta técnica expansível. Escreva sua própria equipe e conte ao mundo
sobre isso. Vamos tentar fazer alguma validação personalizada.

//validação personalizada

Validador::extend('customValidator',

função($campo, $valor, $parâmetros)

{ return $valor == 'customValidator';

});

Rota::get('/', function()

return Visualização::make('formulário');

});

Rota::post('/registrationPage', function()

113
Capítulo 15-Mais sobre validação

// Obtendo todos os dados solicitados.

$dados = Entrada::todos();

// Vamos construir o conjunto de restrições de validação.

$regras = array(

'nome de usuário'

=> 'customValidator',

);

// Criando uma nova instância do validador.

$validatingData = Validador::make($data, $rules);

if ($validatingData->passes()) {

// aqui geralmente fazemos alguma equipe do banco de dados return 'Os dados foram salvos.';

return Redirect::to('/') ->withErrors($validatingData);

});

//fim do código

Como você pode ver, acabei de estender a classe Validator com um método 'extend'. Basicamente, o que
queríamos fazer é construir algumas regras de validação personalizadas. Então emValidador::extend() método
que precisamos para passar essas regras. Usamos um Closure para fazer isso. Se olharmos de pertoampliar()
método:

Validador::extend('customValidator',

função($campo, $valor, $parâmetros)

return $valor == 'customValidator';

});

//fim do código

114
Capítulo 15-Mais sobre validação

Vemos que o primeiro parâmetro é um apelido, nada mais. Mas o segundo parâmetro
é o fechamento, que desempenha o papel principal.
Passa $campo, $valor, $parâmetros. O primeiro parâmetro é o campo (aqui é 'nome de
usuário') e o segundo é o valor do campo. Mas e o terceiro que passa os parâmetros? É uma
matriz de quaisquer parâmetros que foram passados para as regras de validação. Você pode
personalizá-lo em uma aula personalizada. Sem problemas. E finalmente, apenas para
mostrar o exemplo, mantenho o seguinte em nosso arquivo app/routes.php:

Validador::extend('customValidator',

função($campo, $valor, $parâmetros)

return $valor == 'customValidator';

});

Mas você pode mantê-lo em qualquer arquivo do seu ‘app’. E a mesma regra se aplica à incrível classe
personalizada que você irá escrever. Suponha que em ‘app’ você crie uma pasta chamada ‘validator’ e mantenha
sua classe Custom Validation dentro dela assim:

//classe de validação personalizada

classe MyCustomValidation

função pública customValidator($campo, $valor, $parâmetros)

return $valor == 'customValidator';

//fim do código

A questão é: como você pode usá-lo dentro do seu 'routes.php'? Como você pode ver
dentro da classe, retornamos o apelido ‘customValidator’. Podemos vinculá-lo ao método
extend() assim:

//início do código

//validação personalizada

115
Capítulo 15-Mais sobre validação

Validador::extend('customValidator',

MyCustomValidation@customValidator);

Rota::get('/', function()

return Visualização::make('formulário');

});

Rota::post('/registrationPage', function()

// Obtendo todos os dados solicitados.

$dados = Entrada::todos();

// Vamos construir o conjunto de restrições de validação.

$regras = array(

'nome de usuário'

=> 'customValidator',

);

// Criando uma nova instância do validador.

$validatingData = Validador::make($data, $rules);

if ($validatingData>passes()) {

// aqui geralmente fazemos alguma equipe do banco de dados return 'Os dados foram salvos.';

retornar Redirecionamento::para('/')
> withErrors($validandoDados);

});

//fim do código

116
Capítulo 15-Mais sobre validação

A mensagem de validação personalizada é bastante simples e não exige muito esforço. Nas regras de
validação personalizadas existentes você pode fazer isso. E não importa, isso não o colocará em um teste
difícil. Deixe-me garantir que é uma experiência de codificação indolor e prazerosa. Vamos ver como
podemos usar uma mensagem de validação personalizada junto com nossa classe ‘MyCustomValidation’.

//iniciando o código

//mensagem de validação personalizada

//validação personalizada

::extend('customValidator',

função($campo, $valor, $params)

return $valor == 'customValidator';

});

Rota::get('/', function()

return Visualização::make('formulário');

});

Rota::post('/registrationPage', function()

// Obtendo todos os dados solicitados.

$dados = Entrada::todos();

// Vamos construir o conjunto de restrições de validação.

$regras = array(

'nome de usuário'

=> 'min:3',

);

117
Capítulo 15-Mais sobre validação

//

$errorMessages = array('min' => 'Não menos que três caracteres.');

// Criando uma nova instância do validador.

$validatingData = Validador::make($data, $rules, $errorMessages);

if ($validatingData>passes()) {

// aqui geralmente fazemos alguma equipe do banco de dados return 'Os dados foram salvos.';

return Redirect::to('/') ->withErrors($validatingData);

});

//classe de validação personalizada

//em app/validator/MyCustomValidation.php

classe MyCustomValidation

função pública customValidator($campo, $valor, $parâmetros)

return $valor == 'customValidator';

//fim do código

No código anterior, esta parte é extremamente importante.

$mensagensdeerro = array(

'min' => 'Não menos que três caracteres.'

);

// Criando uma nova instância do validador.

118
Capítulo 15-Mais sobre validação

$validatingData = Validador::make($data, $rules, $errorMessages);

if ($validatingData>passes()) {

// aqui geralmente fazemos alguma equipe do banco de dados return 'Os dados foram salvos.';

return Redirect::to('/')->withErrors($validatingData);

});

//fim do código

Você vê, neste $validatingData = Validador::make($data, $rules, $errorMessages);


método, o terceiro parâmetro é opcional para passar mensagens de erro. Ele passa uma série
de mensagens. Se você não definir ou personalizar, ele passará uma mensagem padrão. Se
você tiver uma mensagem habitual, ela substituirá a mensagem padrão. É isso. Aqui acontece
exatamente a mesma coisa.

15.3 Como funciona a validação de formulário


A validação de formulário no Laravel 5 torna-se extremamente fácil. Você viu isso no capítulo anterior. Você
não precisa validar os campos do formulário separadamente. Basta declará-lo em seu método Controller e o
scaffolding do Model e Views está pronto para obedecer a essa regra. Vamos ver como podemos fazer isso da
maneira mais curta! Assumimos que temos uma tabela de 'músicas'. Espero que você não tenha esquecido.
Mostrei antes como adicionar novos registros através da folha do formulário. Agora vamos verificar os
códigos ‘SongsController’. Existe algum método de validação?
Não, então precisamos criá-lo primeiro. Lembre-se, a classe controladora base do Laravel usa o trait
‘ValidatesRequests’, que na verdade trata cada solicitação HTTP com um mecanismo de validação
muito poderoso. Então você não precisa se preocupar com isso. Você precisa adicionar apenas o
método activate() e, uma vez adicionado, ele cuidará de cada solicitação HTTP.

//código inicial

armazenamento de função pública()

$this>validate($this>request, [

'title' => 'obrigatório|único:músicas|

máximo: 255',

'slug' => 'obrigatório||máx:255'

119
Capítulo 15-Mais sobre validação

]);

$this->músicas->title = $this>request

> título;

$this->músicas>slug = $this>request>slug;

$this->músicas->letras = $this>
request>letras;

$this->músicas->save();

retornar 'Salvo';

//código finalizado

E posteriormente adicionamos um método $errors->all() em nossa página 'createsongs.blade.php'


como este:

@foreach ($erros->all() como $erro)

<li>

{{ $ erro }}

</li>

@endforeach

Na sua página 'createsongs.blade.php' você também pode detectar seus erros por esta lógica:

@if (contagem($erros) > 0)

<div class="alert alertdanger">

<ul>

@foreach ($errors->all() como

$erro)

<li>{{ $erro }}</li>

@endforeach

120
Capítulo 15-Mais sobre validação

</ul>

</div>

@fim se

Portanto, há muitas maneiras de fazer suas regras de validação funcionarem. Consulte a


documentação para ver toda a lista de regras de validação disponíveis. Por exemplo, vamos tentar um
exemplo simples. Mude esta linha daquela:

'título' => 'obrigatório|único:músicas|máx:255',

para isso:

'título' => 'obrigatório|único:músicas|máx:255|min:2',

Agora, se você preencher o campo do título com um caractere, ele detectará imediatamente o erro e o
mostrará. O título deve ter pelo menos dois caracteres. E há muitas opções para você se quiser fazer uma
regra de validação personalizada. Você pode usar sua ferramenta artesanal para criar a classe validadora
personalizada assim:

php artesão make:request StoreSongsPostRequest

Agora a classe gerada será armazenada no diretório 'app/Http/Requests'. Então você pode adicionar
algumas regras personalizadas como antes:

função pública myrules()

retornar [

'title' => 'obrigatório|único:músicas|

:255',

'slug' => 'obrigatório||máx:255|min:2',

'letras' => 'obrigatório',

];

Agora, como você pode fazer essa validação personalizada funcionar? Muito simples, você pode
criar a instância da classe recém-criada em sua construção ou então usar o método store() digitando o
objeto de solicitação assim:

121
Capítulo 15-Mais sobre validação

//código inicial

armazenamento de função pública (StoreSongsPostRequest $ solicitação)

$request>myrules($this>request, [

'title' => 'obrigatório|único:músicas|

máx: 255 | min: 2',

'slug' => 'obrigatório||máx:255|min:2',

'letras' => 'obrigatório',

]);

$this>músicas>title = $this>
request>title;

$this->músicas->slug = $this>request>slug;

$this>músicas>letras = $this>
request>letras;

$this>músicas>salvar();

retornar 'Salvo';

//código finalizado

Ao final deste capítulo, podemos concluir que a partir do Laravel 5, o framework tornou a vida
do desenvolvedor muito mais fácil com vários truques fornecidos. Na verdade, a menos que haja uma
situação extraordinária, você não precisa personalizar as suas regras de validação.

122
CAPÍTULO 16

Relações Eloquentes

Agora aprendemos a criar tabelas através do Migration e do Tinker. Também podemos usar o Eloquent ORM
para fazer o mesmo. Também aprendemos a atualizar ou editar os registros do nosso banco de dados.
Suponha que fizemos três tabelas: 'usuários', 'músicas' e 'cantores'. Agora em nossa tabela 'songs' temos duas
tablecells, como você provavelmente notou. Um é ‘user_id’ e o outro é ‘singer_id’. Presumivelmente, um
usuário insere uma música e ele tem um ID. No meu banco de dados inseri três usuários: primeiro, segundo e
terceiro. Portanto, eles têm IDs de usuário como 1, 2 e 3, respectivamente.

Também inseri 10 músicas, que obviamente possuem 10 IDs de músicas respectivos. Finalmente tenho
cinco cantores que têm suas músicas na tabela ‘músicas’. Lembre-se, esses cantores podem ter uma ou duas
músicas. Alguém pode não ter nenhuma música. Além disso, esses cantores também possuem uma chave
estrangeira 'user_id'; ou seja, quando um usuário insere o nome de um cantor naquela tabela seu ID é inserido
junto com ele. Portanto, existe um relacionamento entre essas três tabelas, e esse relacionamento pode ser
explicado em muitas versões formatadas. Mas o Eloquent facilita o trabalho de gerenciar e trabalhar com esses
relacionamentos e oferece suporte a vários tipos diferentes de relacionamentos. Eles são os seguintes:

• Um a um

• Um para muitos

• Muitos para muitos

• Tem muitos através

• Relações Polimórficas

• Relações Polimórficas Muitos para Muitos

Agora vamos explorar esses relacionamentos um por um usando o Eloquent ORM no


Laravel 4 também. Afinal, o que é Eloquent ORM? Até agora você já ouviu falar sobre MVC, que é
a metodologia ModelViewController, mas não falamos nada sobre a parte Model.
Agora, com base nessa teoria, assumimos que a cada tabela do banco de dados temos um Modelo
associado. Podemos interagir com a mesa com muita facilidade.
Já vimos como o Laravel tornou toda a operação do banco de dados bastante
fácil, e o Eloquent é a nova adição a ele.
Se você quiser uma definição, Eloquent é a implementação do Active Record para operações de banco
de dados. Agora, qual é o padrão Active Record? Esta é uma técnica que envolve o banco de dados em
objetos. Suponha que você tenha uma tabela 'usuário'. Você pode apresentar os dados dessa tabela como
uma classe e cada linha como um objeto.

© Sanjib Sinha 2017 123


S. Sinha,Começando o Laravel, DOI 10.1007/978-1-4842-2538-7_16
Capítulo 16-relações eloquentes

Agora cada tabela do banco de dados possui um modelo correspondente que fará todas as operações
que o CRUD realiza. Você conhece CRUD: criar, recuperar, atualizar e excluir. Agora você pode fazer isso
facilmente através do Eloquent ORM. O que é ORM? Mapeamento de relação de objeto. Ou seja, você pode
ter um conjunto definido de relações entre as tabelas correspondentes.
Como vimos em nosso processo de construção de consultas ao banco de dados, uma tabela pode ter muitas
relações entre outras tabelas. Eloquent ORM tem um relacionamento integrado. Isso torna nossa vida muito mais fácil.

A partir do Laravel 4.1, o Eloquent se torna mais poderoso, pois anexou um recurso muito solicitado: o
relacionamento polimórfico Muitos para Muitos. Agora você não precisa escrever muito código para
estabelecer um relacionamento polimórfico Muitos para Muitos entre tabelas. Eloquent faz isso com bastante
facilidade. Temos a tabela 'usuários' e uma classe 'Usuário' em nosso modelo assim:

//código inicial

//modelos/User.php

<?php

use Illuminate\Auth\UserTrait;

use Illuminate\Auth\UserInterface;

use Illuminate\Auth\Reminders\RemindableTrait;

use Illuminate\Auth\Reminders\RemindableInterface;

classe Usuário estende implementos do Eloquent

UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

/**

* A tabela do banco de dados usada pelo modelo.

* @var string

*/

protegido $tabela = 'usuários';

/**

* Os atributos excluídos do formulário JSON do modelo.

124
Capítulo 16-relações eloquentes

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

//fim do código

Agora em nosso Routes.php temos um código como este:

//código inicial

//rotas.php

Rota::get('/', function()

$usuário = Usuário::todos();

var_dump($usuário);

});

//fim do código

Como temos quatro usuários até agora, a saída anterior mostra-os um por um
em todo o par chave=>valor. Começa em 0 e termina em 3.
O que isso diz? Diz que esta representação é de um objeto da classe Model User. Na
classe User você já definiu duas propriedades:

//fragmento de código de User.php

/**

* A tabela do banco de dados usada pelo modelo

* @var string

*/

125
Capítulo 16-relações eloquentes

protegido $tabela = 'usuários';

/**

* Os atributos excluídos do formulário JSON do modelo

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

//código está incompleto

Agora compare-os com estas duas linhas: protected 'table' => string 'users' (length=5)
protected 'hidden' => array (size=2)…
Espero que esta comparação inspire você a definir mais propriedades na classe User! E o
que pode ser definido está sendo dito na saída anterior.
Existem muitas propriedades como 'conexão', 'relações', 'guardado', 'preenchível', etc. Agora
esperamos que você entenda que essas propriedades podem ser definidas em sua classe User: não
apenas na classe User em sua pasta Models, mas em qualquer classe que você mesmo escreverá.
Suponha que temos outra tabela chamada ‘contatos’. Podemos criar uma classe Contact em nossa
pasta Models. Vamos criá-lo com poucas propriedades.

//código inicial

//modelos/Contato.php

<?php

classe Contato estende Eloquent{

/**

* A tabela do banco de dados usada pelo modelo

* @var string

*/

protegido $tabela = 'contatos';

126
Capítulo 16-relações eloquentes

//fim do código

Agora vamos ao nosso Routes.php e altere o código para isto:

//código inicial

//rotas.php

Rota::get('/', function()

$usercontacts = Contato::all();

var_dump($contatosdousuário);

});

//fim do código

Temos a mesma saída de antes, como a tabela 'usuários', com apenas uma exceção. A única
exceção está nesta linha:

'tabela' protegida => string 'contatos' (comprimento = 8)

Basicamente, exceto isso, todas as propriedades são predefinidas, mas a qualquer momento você
pode substituí-las assim. Na sua classe User, você escreve algo assim:

//código inicial

//Usuário.php

classe Usuário estende Eloquent {

protegido $guardado = array('senha');

//fim de User.php

Isso significa que a 'senha' da tabela 'usuários' não pode mais ser atribuída em massa. Você pode
até bloquear todos os atributos da atribuição em massa como este:

protegido $guardado = array('*');

Portanto, as possibilidades são infinitas. E mais tarde voltaremos a essas propriedades e discutiremos
de maneira detalhada. Antes disso, eu examinaria algumas construções de consultas normalmente definidas
em nossos modelos. Suponha que queremos encontrar o país do primeiro

127
Capítulo 16-relações eloquentes

Contatos. O Laravel Eloquent ORM vem com uma metodologia razoavelmente moderada que pode
ajudá-lo a encontrá-lo facilmente.
Considere este código:

Rota::get('/', function()

$contatosdousuário = Contato::find(1);

var_dump($usercontacts>país);

});

Podemos ver todos os contatos em uma forma JSON bem formatada? Vamos ver:

Rota::get('/', function()

$usercontacts = Contato::all();

foreach ($usercontacts as $key => $value) {

echo $chave. "=" . $valor. "<br>";

});

A saída JSON é assim:

0={"id":"1","user_id":"1","address":"Endereço do administrador","país":"Marte","telefone
um":"12445"}

1={"id":"2","user_id":"2","address":"Endereço de Sanjib","country":"Júpiter" ,
"phone":"456"}

2={"id":"3","user_id":"3","address":"Endereço de Debangshu","country":"Moon" ,
"phone":"567"}

3={"id":"4","user_id":"8","address":"Endereço de
Mana","country":"Sun","phone":"234"}

Parece que o Laravel pensou nisso antes e está tentando usar a vantagem do JSON ou JavaScript
Object Notation. Essencialmente, é uma maneira legível por humanos de armazenar o valor de um
array ou de um objeto como strings. Basta pegar o primeiro valor da primeira linha da nossa tabela de
Contatos e ver o que ele diz.

128
Capítulo 16-relações eloquentes

0={"id":"1","user_id":"1","address":"Endereço do
administrador","country":"Mars","phone":"12445"}

Diz: nosso objeto $contact produz um array que contém todos os valores da tabela 'contatos'. A
primeira chave, que obviamente é 0, representa a primeira linha da tabela de 'contatos'.
Agora você pode perguntar, por que o Laravel escolhe JSON? Há muitas razões, mas uma delas é
definitivamente a velocidade. O uso comum de JSON é quando uma parte front-end do seu aplicativo
deseja dados do back-end sem carregamento de página.
O mesmo objetivo pode ser alcançado por JavaScript com uma solicitação AJAX. A velocidade
realmente importa quando você lida com um aplicativo muito grande, não é?
Não ficará fora de contexto se discutirmos um pouco sobre JSON aqui. Espero que você me
permita lhe contar algo mais. Para um iniciante é bom saber que o PHP começa a serializar arrays e
objetos para JSON a partir de sua versão 5.2.0. Você deve ter ouvido falar dos métodos serialize() e
unserialize() em PHP. Nada mais é do que converter um objeto em string e reverter para uma nova
instância para recuperar seu valor.
Eu disse que JSON é legível por humanos, mas praticamente não é muito legível, pois JSON armazena
dados sem espaços em branco entre eles. Por que? Como eu disse, a velocidade é importante! Agora, de volta à
nossa antiga discussão. A saída significa que cada objeto de linha de contato foi incluído em uma matriz.
Portanto, podemos quebrá-los para tirar mais proveito disso:

Rota::get('/', function()

$contato = Contato::todos();

foreach ($contato como $valor){

var_dump($valor);

});

Agora a saída é extremamente importante e mostra explicitamente como a classe Contact


se comporta e cria seu objeto. Aqui vemos quatro objetos de contato, cada um com suas
propriedades bem definidas. Estendemos nossa classe Contact do Eloquent e, assim, herdamos
essas propriedades.
Estamos interessados na primeira parte da saída anterior:

objeto(Contato)[141]

'tabela' protegida => string 'contatos' (comprimento = 8)

'conexão' protegida => nulo

protegido 'primaryKey' => string 'id' (comprimento = 2)

129
Capítulo 16-relações eloquentes

protegido 'porPágina' => int 15

public 'incrementando' => boolean true

público 'timestamps' => booleano verdadeiro

'atributos' protegidos =>

matriz (tamanho = 5)

'id' => string '1' (comprimento = 1)

'user_id' => string '1' (comprimento = 1)

'endereço' => string 'Endereço do administrador' (comprimento = 16)

'país' => string 'Marte' (comprimento = 4)

'telefone' => string '12445' (comprimento = 5)

protegido 'original' =>

matriz (tamanho = 5)

'id' => string '1' (comprimento = 1)

'user_id' => string '1' (comprimento = 1)

'endereço' => string 'Endereço do administrador' (comprimento = 16)

'país' => string 'Marte' (comprimento = 4)

'telefone' => string '12445' (comprimento = 5)

'relações' protegidas =>

matriz (tamanho = 0)

vazio

......

Você vê que esta saída está incompleta, mas serve ao propósito. Existem muitas
propriedades como 'tabela', 'conexão', 'atributos', 'original', etc. Cada propriedade é uma matriz.
E finalmente o Laravel os produz em JSON. Agora para recuperar todos os dados basta pegar a
chave e o valor ficará assim:

//código inicial

130
Capítulo 16-relações eloquentes

Rota::get('/', function()

$contato = Contato::todos();

foreach ($contato como $valor){

echo "ID de contato = ". $valor->id . "<br>";

echo "ID do usuário = ". $valor->user_id .

"<br>";

echo "Endereço = ". $valor->endereço.

"<br>";

echo "País = ". $valor->país .

"<br>";

eco "Telefone = ". $valor->telefone.

"<br><br><br>";

//var_dump($valor) . "<br>";

});

//fim do código

E o resultado é bastante esperado. Ele mostra todos os detalhes dos contatos com ID do usuário.

//a saída

ID de contato = 1

ID do usuário = 1

Endereço = Endereço do Administrador

País = Marte

Telefone = 12445

131
Capítulo 16-relações eloquentes

ID de contato = 2

ID do usuário = 2

Endereço = Endereço de Sanjib

País = Júpiter

Telefone = 456

ID de contato = 3

ID do usuário = 3

Endereço = Endereço de Debangshu

País = Lua

Telefone = 567

ID de contato = 4

ID do usuário = 8

Endereço = Endereço de Mana

País = Sol

Telefone = 234

//fim da saída

O ponto crucial do modelo Eloquent é este. Agora vamos fazer algumas consultas com nosso modelo
Eloquent. Primeiro verificaremos com base na idade do usuário. Temos a classe User definida anteriormente.
Primeiro, queremos verificar dois usuários com idades correspondentes superiores a 18 anos.

//código inicial

Rota::get('/', function()

$usuários = Usuário::where('idade', '>', 18)


> pegue(2)

> obter();

foreach ($usuários como $usuário)

132
Capítulo 16-relações eloquentes

var_dump($usuário>nomedeusuário);

});

//fim do código

Lembre-se de que temos apenas três usuários em nossa tabela de usuários com idade acima de 18 anos. Obtemos os dois
primeiros.

//saída

string 'admin' (comprimento = 5)

string 'sanjib' (comprimento = 6)

//fim da saída

Ele produz com base no ID do usuário. Continua 1, 2, 3 e assim por diante. Se houver
milhões de usuários e você não precisar processá-los todos para evitar consumir sua memória,
um bom método é chunk(). Com apenas quatro usuários é difícil mostrar como funciona, mas
ainda assim podemos tentar e nos divertir.

//código inicial

Usuário::chunk(100, função($usuários)

foreach ($usuários como $usuário)

//pegue o $user aqui

});

//fim do código

Inserir, atualizar ou excluir com a ajuda do Eloquent é bastante fácil, como você já supôs. Você
não precisa escrever muito código; em vez disso, você escreve apenas duas ou três linhas de código
para realizar seu trabalho de maneira segura.

133
Capítulo 16-relações eloquentes

//código inicial

Rota::get('/', function()

$usuário = novo usuário();

$usuário->nomedeusuário = 'NovoUsuário';

$usuário->senha = senha_hash('senha', PASSWORD_BCRYPT);

$usuário->token = 'kljhnmbgfvcdsazxwetpouytresdfhjkmnbbvcdsxza';

$usuário>idade = 27;

$usuário->criado_at = tempo();

$usuário>atualizado_at = hora();

$usuário>salvar();

return 'NovoUsuário Salvo';

});

//fim da codificação

Vamos ver como o novo usuário ‘NewUser’ foi criado em nossa tabela ‘users’. Ver seus detalhes
é muito fácil agora. Sabemos a idade dele, ou seja, 27 anos. Então anote este código:

//código inicial

Rota::get('/', function()

$usuários = Usuário::where('idade', '=', 27)>get();

foreach ($usuários como $usuário) {

var_dump($usuário);

});

//fim da codificação

134
Capítulo 16-relações eloquentes

Agora sabemos como será a aparência desse novo objeto de usuário quando usarmos o método var_
dump(). Existem vários métodos create() de modelos Eloquent. Você pode criar vários usuários de uma só
vez. Além disso, você pode recuperar e atualizar qualquer usuário com uma quantidade mínima de
codificação como esta:

//código inicial

Rota::get('/', function()

$usuário = Usuário::find(2);

$usuário>nomedeusuário = 'babu';

$usuário->salvar();
retornar 'Salvo!';

});

//fim da codificação

Sabemos que o segundo usuário era 'sanjib', mas agora foi salvo com sucesso em 'babu'. Excluir
é muito mais fácil do que antes. Se quisermos excluir o usuário 'NewUser', precisamos escrever sql
assim:

"DELETE FROM `sanjib`.`users` ONDE `users`.`id` = 10"?

Não é bastante longo? Porque antes desta linha você precisa se conectar manualmente ao seu
banco de dados, etc. No Eloquent Models é muito mais fácil, pois você já tem tudo configurado de
antemão. O código é simples:

//código inicial

$usuário = Usuário::find(10);

$usuário->delete();

//fim da codificação

Antes de concluir nossa discussão sobre o Eloquent, gostaria de dizer algo novamente sobre
essas propriedades. Sempre que você for criar uma nova classe em seus modelos Eloquent, você
terá algumas propriedades já definidas e configuradas. Laravel fez isso por padrão. Já vimos essas
propriedades antes. Um deles são os carimbos de data/hora. Por padrão, o Eloquent mantém as
colunas criadas_at e atualizadas_at do seu banco de dados automaticamente e você não precisa se
preocupar com isso.
Suponha que você execute um código como este para obter todos os usuários pertencentes ao grupo com menos de 28 anos.

135
Capítulo 16-relações eloquentes

//código inicial

Rota::get('/', function()

$usuários = Usuário::where('idade', '<', 28)


> pegue(2)->get();

foreach ($usuários como $usuário)

var_dump($usuário);

});

//fim do código

Conhecemos o resultado e por isso não o repetimos mais. Mas observe essas propriedades, como
'carimbos de data e hora', 'preenchível' ou 'guardado'. Enquanto o Eloquent os mantiver, não há problema,
mas se quisermos alterá-los de acordo com os nossos critérios: então o que acontece?
Vamos cuidar disso. Suponha que queiramos tornar os carimbos de data e hora 'falsos' e também trazer algumas
alterações nas propriedades 'preenchíveis' e 'protegidas'. O código fica assim em nossa classe User antes de alterar as
propriedades:

//código inicial

//modelos/User.php

<?php

use Illuminate\Auth\UserTrait;

use Illuminate\Auth\UserInterface;

use Illuminate\Auth\Reminders\RemindableTrait;

use Illuminate\Auth\Reminders\RemindableInterface;

classe Usuário estende implementos do Eloquent

UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

136
Capítulo 16-relações eloquentes

/**

* A tabela do banco de dados usada pelo modelo.

* @var string

*/

protegido $tabela = 'usuários';

/**

*Os atributos excluídos do modelo

Formulário JSON.

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

público $timestamps = falso;

protegido $preenchível = array('nomedeusuário', 'token');

protegido $guardado = array('id', 'senha');

//fim do código

Como você pode ver, comentei essas propriedades. Agora vamos mudar a
classe User, e o código final fica assim:

//código inicial

//modelos/User.php

<?php

use Illuminate\Auth\UserTrait;

use Illuminate\Auth\UserInterface;

137
Capítulo 16-relações eloquentes

use Illuminate\Auth\Reminders\RemindableTrait;

use Illuminate\Auth\Reminders\RemindableInterface;

classe Usuário estende implementos do Eloquent

UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

/**

* A tabela do banco de dados usada pelo modelo.

* @var string

*/

protegido $tabela = 'usuários';

/**

*Os atributos excluídos do modelo

Formulário JSON.

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

público $timestamps = falso;

protegido $preenchível = array('nomedeusuário', 'token');

protegido $guardado = array('id', 'senha');

//fim do código

138
Capítulo 16-relações eloquentes

As tabelas do banco de dados possuem relações entre elas. É obviamente verdade que um usuário
faria seu pedido sabendo que o pedido seria adicionado à sua conta. Três tabelas são associadas
instantaneamente. O Eloquent torna essa parte de gerenciamento bastante fácil. Em nosso banco de
dados anterior, 'sanjib', temos duas tabelas relacionadas: 'usuários' e 'contatos'. Em nossa classe User
vamos escrever um método que corresponda ao Modelo de Contato. Ou seja, um usuário possui um
contato. O Laravel já possui o método: hasOne(), que passa um parâmetro que tem relação com aquele
Model.

//código inicial

//modelos/User.php

<?php

use Illuminate\Auth\UserTrait;

use Illuminate\Auth\UserInterface;

use Illuminate\Auth\Reminders\RemindableTrait;

use Illuminate\Auth\Reminders\RemindableInterface;

classe Usuário estende implementos do Eloquent

UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

/**

* A tabela do banco de dados usada pelo modelo

* @var string

*/

protegido $tabela = 'usuários';

/**

*Os atributos excluídos do modelo

Formulário JSON

139
Capítulo 16-relações eloquentes

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

público $timestamps = falso;

protegido $preenchível = array('nomedeusuário', 'token');

protegido $guardado = array('id', 'senha');

contato de função pública()

return $this->hasOne('Contato');

//fim do código

Em nossa tabela 'usuários', o nome de usuário 'mana' possui ID de usuário 8. Em 'contatos' ela possui ID primário
4, mas possui um user_id correspondente 8. Portanto, nossa intenção é chegar à tabela 'contatos' através do Modelo de
Usuário. Por esse motivo adicionamos esta metodologia ao Modelo do Usuário:

contato de função pública()

return $this->hasOne('Contato');

Agora, quando escrevemos em nosso Routes.php, codifique assim:

//código inicial

//rotas.php

Rota::get('/', function()

$contato = Usuário::find(8)->contato;

140
Capítulo 16-relações eloquentes

var_dump($contato);

});

//fim do código

Na verdade, alcançamos a tabela 'contatos' através de nosso modelo de usuário e descobrimos


cujo user_id é 8. A saída sai diretamente da tabela 'contatos' e produz os contatos detalhados do
usuário 'mana'.
Não há nada de novo nisso. Basicamente o SQL executado neste código corresponde a isto:

//instrução SQL

selecione * dos usuários onde id = 8

selecione * nos telefones onde user_id = 8

//fim da instrução SQL

Esse relacionamento é chamado de Um para Um. Você pode definir o inverso do relacionamento no
Modelo de Contato usando o método pertenceTo() passando o nome da tabela como seu primeiro parâmetro.
Nesse caso, em nossa classe Contact, escreveremos um código como este:

//código inicial

//modelos/Contato.php

<?php

classe Contato estende Eloquent{

/**

* A tabela do banco de dados usada pelo modelo.

* @var string

*/

protegido $tabela = 'contatos';

usuário de função pública()

141
Capítulo 16-relações eloquentes

return $this>belongsTo('Usuário');

//fim do código

Agora, se escrevermos este código em nosso Routes.php:

//código inicial

//rotas.php

Rota::get('/', function()

$contato = Contato::find(4)->usuário;

var_dump($contato);

});

//fim do código

Isso significa que em nossa tabela de 'contatos' pesquisamos todo o ID e vemos se ele possui um user_id
correspondente a ele. Atualmente, em nossa tabela de 'contatos' temos o user_id 10 correspondente ao ID de
contatos 4. Este relacionamento significa que o ID de contatos 4 possui todos os detalhes do usuário na tabela
de 'usuários' e consulta seu user_id correspondente para ver qual é o número existe. Neste caso, o ID de
contatos 4 possui um user_id 10 correspondente. Portanto, está convencido de que na tabela 'usuários' ele
possui um ID 10. Na tabela de usuários o ID 10 pertence ao nosso usuário recém-criado 'NewUser'. Algumas
páginas atrás, criamos 'NewUser' através do método insert usando Eloquent.

Em última análise, traz a saída de 'NewUser'. Agora você precisa entender aquela
pequena diferença complicada entre esses dois métodos:

//Usuário.php

contato de função pública()

return $this->hasOne('Contato');

//Contato.php

142
Capítulo 16-relações eloquentes

usuário de função pública()

return $this->belongsTo('Usuário');

Este hasOne() na classe de usuário procura o user_id correspondente na tabela 'contatos' e


pertenceTO() em Contact.php apenas relaciona seu ID primário ao user_id correspondente nessa
tabela. De qualquer forma, user_id desempenha o papel vital e define o relacionamento Um para
Um, mas de uma maneira diferente.
Da mesma forma, podemos facilmente estabelecer relacionamentos Um para Muitos entre tabelas. Suponha que um
usuário tenha muitas postagens em nossa tabela de 'postagens'. Como podemos obter todos os seus artigos de uma só vez?

Existe um método, hasMany(), que passa parâmetros semelhantes que podem fazer essa consulta SQL
com muita facilidade. Em nosso modelo de usuário, primeiro devemos definir esse método desta forma:

//código inicial

//modelos/User.php

<?php

use Illuminate\Auth\UserTrait;

use Illuminate\Auth\UserInterface;

use Illuminate\Auth\Reminders\RemindableTrait;

use Illuminate\Auth\Reminders\RemindableInterface;

classe Usuário estende implementos do Eloquent

UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

/**

* A tabela do banco de dados usada pelo modelo

* @var string

*/

143
Capítulo 16-relações eloquentes

protegido $tabela = 'usuários';

/**

*Os atributos excluídos do modelo

Formulário JSON

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

público $timestamps = falso;

protegido $preenchível = array('nomedeusuário', 'token');

protegido $guardado = array('id', 'senha');

contato de função pública()

return $this->hasOne('Contato');

postagem de função pública()

return $this->hasMany('Post');

//fim do código

E depois disso, pegaremos todos os artigos escritos por qualquer user_id mencionado na tabela 'posts'
em nosso arquivo Routes.php. E o código é o seguinte:

//código inicial

//rotas.php

144
Capítulo 16-relações eloquentes

Rota::get('/', function()

$postagens = Usuário::find(10)>postagem;

foreach ($postagens como $valor) {

echo "Esta postagem feita pelo


ID do usuário: {$value>user_id} <br>";

eco "Introdução: " . $valor->introdução . "<br>";

echo "Artigo:" .$valor->artigo

"<br>";

echo "Tags: " .$valor->tag

"<br><br><br>";

});

//fim do código

Finalmente, obtemos todos os posts enviados pelo 'NewUser' cujo ID de usuário é 10.
Basicamente, os artigos mostrados aqui são para fins de teste. Agora você pode, com sorte, escrever
seu próprio CMS baseado no Laravel. Finalmente verificaremos o relacionamento Muitos para Muitos.
Existem algumas situações em que os usuários podem ter funções diferentes ao mesmo tempo. Vamos
primeiro adicionar uma tabela ao nosso banco de dados: funções. Em seguida, atribua alguma coluna
como id, nome, criado_at e atualizado_at. Agora temos quatro funções: Administrador, Moderador,
Colaborador e Membro. Tivemos cinco usuários. Alguns deles têm funções comuns: por exemplo, o
usuário 'admin' é Administrador, Moderador e Colaborador. O usuário 'NewUser' também é assim. Os
restantes têm funções diferentes: por exemplo, o utilizador 'babu' é Moderador e também Colaborador,
etc. Este é um relacionamento muito complexo, mas o Laravel vem com uma solução muito simples. Ele
possui um método chamado pertenceToMany() que definiria esse relacionamento, mas precisamos de
uma tabela intermediária para unir duas tabelas: usuários e funções. Essa tabela intermediária é
chamada 'role_user'. O nome é derivado da ordem alfabética dos nomes dos modelos relacionados. A
tabela 'role_user' deve ter duas colunas: role_id e user_id. Dessa forma, você pode construir relações
Muitos para Muitos com bastante facilidade.

/* Temos a tabela role_user preenchida com diferentes responsabilidades. Você pode


executar esse SQL de uma só vez para testar seu aplicativo. Basta criar a tabela
'role_user' no seu banco de dados 'sanjib' e executar este SQL: */

//role_user.SQL

145
Capítulo 16-relações eloquentes

- - Despejo SQL do phpMyAdmin

- - versão 4.0.10deb1

- - http://www.phpmyadmin.net

--

- - Host: localhost

- - Horário de geração: 30 de março de 2015 às 20h43

- - Versão do servidor: 5.5.41-0ubuntu0.14.04.1

- - Versão PHP: 5.5.21-1+deb.sury.org~precise+2

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";

DEFINIR fuso_horário = "+00:00";

/*!40101 CONJUNTO

@OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

/*!40101 CONJUNTO

@OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

/*!40101 CONJUNTO

@OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;

/*!40101 DEFINIR NOMES utf8 */;

--

- - Banco de dados: `sanjib`

--

---------------------------------------------------------

--

- - Estrutura da tabela `role_user`

--

146
Capítulo 16-relações eloquentes

CRIAR TABELA SE NÃO EXISTIR `role_user` (

`id` int(11) NÃO NULO AUTO_INCREMENT,

`user_id` int (11) NÃO NULO,

`role_id` int(11) NÃO NULO,

carimbo de data/hora `created_at` NÃO NULO DEFAULT CURRENT_TIMESTAMP ON

ATUALIZAÇÃO CURRENT_TIMESTAMP,

carimbo de data/hora `updated_at` NÃO NULO PADRÃO '0000-00-00 00:00:00',

CHAVE PRIMÁRIA (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

- - Aprendiz Laravel - 608

- - Despejo de dados para a tabela `role_user`

--

INSERT INTO `role_user` (`id`, `user_id`, `role_id`, `created_at`, `updated_ at`)

VALORES

(1, 1, 1, '30/03/2015 15:10:21', '0000-00-00 00:00:00'),

(2, 1, 2, '30/03/2015 15:10:46', '0000-00-00 00:00:00'),

(3, 1, 3, '30/03/2015 15:10:55', '0000-00-00 00:00:00'),

(4, 10, 1, '30/03/2015 15:11:06', '0000-00-00 00:00:00'),

(5, 10, 2, '30/03/2015 15:11:22', '0000-00-00 00:00:00'),

(6, 10, 3, '30/03/2015 15:11:31', '0000-00-00 00:00:00'),

(7, 2, 2, '30/03/2015 15:11:43', '0000-00-00 00:00:00'),

(8, 2, 3, '30/03/2015 15:11:51', '0000-00-00 00:00:00'),

(9, 8, 3, '30/03/2015 15:12:38', '0000-00-00 00:00:00'),

(10, 8, 4, '30/03/2015 15:12:45', '0000-00-00 00:00:00'),

147
Capítulo 16-relações eloquentes

(11, 3, 3, '30/03/2015 15:12:53', '0000-00-00 00:00:00'),

(12, 3, 4, '30/03/2015 15:12:59', '0000-00-00 00:00:00');

/*!40101 CONJUNTO

CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

/*!40101 CONJUNTO

CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;

/*!40101 CONJUNTO

COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

//fim de role_user.SQL

Agora, primeiro de tudo, definiríamos o método em nosso modelo de usuário assim:

//código inicial
//modelos/User.php
<?php

protegido $tabela = 'usuários';

protegido $ oculto = array('senha', 'lembrar_token');

público $timestamps = falso;

protegido $preenchível = array('nomedeusuário', 'token');

protegido $guardado = array('id', 'senha');

contato de função pública()

return $this->hasOne('Contato');

postagem de função pública()

return $this->hasMany('Post');

148
Capítulo 16-relações eloquentes

função de função pública()

return $this->belongsToMany('Role');

//fim do código

Neste método:

função de função pública()

return $this->belongsToMany('Role', 'função_usuário');

Você pode passar explicitamente a tabela dinâmica como o segundo parâmetro. Suponha que você
queira usar o nome da tabela 'users_role' em vez de 'role_user'; então você pode escrever o seguinte:

função de função pública()

return $this>belongsToMany('Role', 'users_role');

É isso. E igualmente agora você pode usar a inversão no Modelo de Papel. O código é
assim:

//código inicial

//modelos/Role.php

<?php

classe Role estende Eloquent{

/**

149
Capítulo 16-relações eloquentes

* A tabela do banco de dados usada pelo modelo.

* @var string

*/

protegido $tabela = 'funções';

usuário de função pública()

return $this->belongsToMany('Usuário');

//fim do código

Agora chegou a hora de testar nosso código. O relacionamento Muitos para Muitos funciona
muito bem agora. O primeiro usuário 'admin' tem três funções diferentes: Administrador, Moderador e
Colaborador. Vamos verificar se em nossas rotas conseguimos ou não:

//código inicial
//rotas.php
Rota::get('/', function()

$roles = Usuário::find(1)->role;

foreach ($funções como $valor) {

var_dump($valor);

});

//fim do código

150
Capítulo 16-relações eloquentes

Estamos tentando descobrir que tipo de funções o usuário 'admin' possui. O usuário 'admin' tem
três funções: Administrador, Moderador e Colaborador. Ele foi mostrado em todo o modelo do usuário.
Agora podemos ter uma inversão deste Modelo. Agora vamos descobrir quais usuários são
Administrador ou Moderador ou Colaborador ou Membro. Tipo, em nosso Routes.php podemos
escrever o código desta forma:

//código inicial

//rotas.php

Rota::get('/', function()

$roles = Role::find(1)->user;

foreach ($funções como $valor) {

var_dump($valor);

});

//fim do código

Neste código, na verdade queremos descobrir quem são os Administradores, porque o ID da


função 1 é Administrador. Aqui estão dois usuários que são administradores. Eles são 'admin' e
'NewUser'. Os dados detalhados sobre eles foram retirados da tabela de 'usuários'. Da tabela 'funções'
até o Modelo de Função, você pode pesquisar qualquer função que tenha sido atribuída aos usuários.
Poderia haver milhares de membros ou colaboradores. Mas em poucas linhas de códigos, o Laravel
torna sua tarefa muito mais simples. No próximo capítulo, veremos mais algumas funcionalidades do
Laravel que tratam de banco de dados.

151
CAPÍTULO 17

Como a segurança e
Trabalho de autenticação
Junto

O Laravel implementa a autenticação de uma forma tão simples que você tem tudo pronto para uso.
Para fazer isso, o Laravel retorna um array em 'app/config/auth.php' onde essas coisas estão definidas
e também bem documentadas. Neste arquivo fica claro que o driver será Eloquent, o modelo será User
e a tabela será ‘users’. Existe outra tabela: 'password_reminder'. Discutiremos isso mais tarde. Então,
por padrão, foi definido; agora tudo que você precisa fazer é usar os métodos estáticos com os quais o
Laravel vem. Para tornar sua senha mais forte, o Laravel possui a classe 'Hash' que fornece hashing
Bcrypt seguro. Você pode tornar sua senha mais forte com este método:

$senha = Hash::make('suasenha');

Podemos verificar como funciona. Vamos ao nosso Routes.php e primeiro descobrir qual
é a senha do usuário 'NewUser'.

//código inicial

//rotas.php

Rota::get('/', function()

$usuário = Usuário::find(10);

echo $usuário->senha;

});

© Sanjib Sinha 2017 153


S. Sinha,Começando o Laravel, DOI 10.1007/978-1-4842-2538-7_17
Capítulo 17-como segurança e autenticação funcionam juntas

//fim do código

A saída é:

$2y$10$XTne1FYOoTLqGYPIiu/7F.4AxUae9akpjpFV.xizdq3IytI9N1Nim

Criamos essa senha com o método PHP password_hash() assim:

$usuário>senha = senha_hash('senha', PASSWORD_BCRYPT);

//fim do método password_has()

Agora podemos atualizar esta senha com o método Hash::make() do próprio Laravel e ver
como fica. Primeiro atualize a senha:

//código inicial

Rota::get('/', function()

$usuário = Usuário::find(10);

$usuário>senha = Hash::make('pass');

$usuário->salvar();

});

//fim do código

Agora a saída se parece com:

//saída

$2 anos$10$NI9gu2x3q78dzE2J.h9kweJaD4I1M27kHokiZ.yfABynpABbNA/zW

//fim da saída

Podemos verificar o comprimento da senha. É uma string e o comprimento é 60. Se


var_dump($user) em nosso Routes.php obtemos todos os detalhes sobre o usuário 'NewUser'
através do modelo User, e a saída indicará o comprimento da senha.
Podemos voltar novamente ao nosso antigo método password_hash() e alterar a senha do
usuário ‘NewUser’ assim:

//código inicial

//rotas.php

154
Capítulo 17-como segurança e autenticação funcionam juntas

Rota::get('/', function()

$usuário = Usuário::find(10);

$usuário>senha = senha_hash('senha', PASSWORD_BCRYPT);

$usuário->salvar();

});

//fim do código

Execute o código e novamente var_dump($user) e veja a saída da senha agora:

//saída

'senha' => string

'$2y$10$zjBulZIfVmMZu/QDGdoCROoKlQysWs/hAVKFTGLNp60EiG5K5zl

WO' (comprimento=60)

//fim da saída

A senha foi atualizada. O comprimento é 60 de qualquer maneira. Você pode se perguntar por
que gasto tanto tempo discutindo senhas! Em primeiro lugar, no que diz respeito à segurança, é
preciso ter cuidado com as senhas. Você deveria torná-los mais fortes. O que eu queria provar aqui é
que o Laravel sempre utiliza o que há de mais avançado em tecnologia disponível em PHP. O mesmo
resultado está disponível através de código com a ajuda do Laravel. Agora vamos tentar algum
processo de autenticação usando as interfaces e métodos padrão com os quais o Laravel vem.

A partir de então encontramos alguns métodos que apontam para o processo de autenticação. Podemos
usá-los em nosso modelo de usuário assim:

//código inicial

//modelos/User.php

<?php

use Illuminate\Auth\UserTrait;

use Illuminate\Auth\UserInterface;

use Illuminate\Auth\Reminders\RemindableTrait;

155
Capítulo 17-como segurança e autenticação funcionam juntas

use Illuminate\Auth\Reminders\RemindableInterface;

classe Usuário estende implementos do Eloquent

UserInterface, RemindableInterface {

use UserTrait, RemindableTrait;

/**

* A tabela do banco de dados usada pelo modelo.

* @var string

*/

protegido $tabela = 'usuários';

/**

* Os atributos excluídos do formulário JSON do modelo

* @var matriz

*/

protegido $ oculto = array('senha', 'lembrar_token');

público $timestamps = falso;

protegido $preenchível = array('nomedeusuário', 'token');

protegido $guardado = array('id', 'senha');

função pública getAuthIdentifier(){

return $this->getKey();
}

função pública getAuthPassword() {

retorne $isto->senha;

156
Capítulo 17-como segurança e autenticação funcionam juntas

postagem de função pública()

return $this->hasMany('Post');

contato de função pública()

return $this->hasOne('Contato');

função de função pública()

return $this->belongsToMany('Role', 'role_user');

//fim do código

Agora você pode criar um sistema de autenticação do tipo ‘dashboard’ para nossa administração. É
bastante simples e curto, mas você entendeu e espero que possa construir seu 'CRUD' com base nesses
conceitos.
Agora é hora de usar as classes 'Auth' e 'Session' e os métodos estáticos necessários em nosso
'routes.php' para tornar este mecanismo de autenticação bem-sucedido.

//código inicial

//rotas.php

::get('/', 'HomeController@home');

Rota::get('/login', 'HomeController@login');

Rota::post('login', function(){

if(Auth::attempt(Input::only('nome de usuário', 'senha'))) {

return Redirect::intended('/');

157
Capítulo 17-como segurança e autenticação funcionam juntas

} outro {

return Redirect::back()->withInput()->with('error', "Credenciais


inválidas");

});

Rota::get('logout', function(){

Autenticação::logout();

return Redirect::to('/')->with('message', 'Você está desconectado');

});

Rota::group(array('before'=>'auth'), function(){

Route::get('/', 'HomeController@home');

Route::get('usuário/{id}', 'HomeController@usuário');

});

//fim do código

Agora vamos explicar os passos um por um: Primeiro precisamos ter uma página de 'índice' protegida. Para
fazer isso, tudo o que precisamos fazer é usar o seguinte:

Rota::group(array('before'=>'auth'), function(){

Route::get('/', 'HomeController@home');

Route::get('usuário/{id}', 'HomeController@usuário');

});

Através deste roteamento de grupo podemos definir quais páginas são apenas para usuários autenticados.
Definimos duas páginas conforme nosso planejamento: 'índice' e 'usuários'.
Também podemos usar o método Auth::logout() para finalizar a sessão, ele redireciona o
usuário novamente para a página ‘index’, que nada mais é do que a página ‘login’. Concluiremos
este capítulo com alguns métodos de autenticação que o Laravel vem por padrão. Para senhas,
você pode usar estes métodos:

//código inicial

Hash::make('suasenha');

158
Capítulo 17-como segurança e autenticação funcionam juntas

Hash::check('suasenha', $hashedPassword);

Hash::needsRehash($hashedPassword);

//fim do código

E para autenticação, você pode usar estes métodos:

//código inicial

Autenticação::verificar();

Autenticação::usuário();

Auth::tentativa(array('email' => $email, 'senha'=> $senha));

Auth::attempt($usercredentials, true);

Auth::once($credenciais do usuário);

Auth::login(Usuário::find(1));

Auth::loginUsingId(1);

Autenticação::logout();

Auth::validate($credenciais do usuário);

Auth::basic('nome de usuário');

Auth::onceBasic();

Senha::remind($usercredentials,

function($mensagem, $usuário){});

//fim do código

159
CAPÍTULO 18

Como solicitação, resposta


Trabalhar no Laravel 5

O que significa solicitação?


Quando um usuário solicita algumas páginas, o que acontece? Você acabou de aprender isso no
capítulo anterior. Podemos obter essa instância de solicitação e ver como fica. Para fazer isso, gostaríamos
de fazer uma espécie de dica de tipo para nossa classe 'Illuminate\Http\Request' em nosso construtor ou
método de controlador. Suponha que temos um 'TestController'.
Então o código ficará assim:

//código inicial

<?php namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Illuminate\Routing\Controller;

classe TestController estende o controlador

solicitação $ protegida;

/**

* @param Solicitação $ solicitação

* @return Resposta

*/

função pública testRequest(Solicitação $solicitação)

© Sanjib Sinha 2017 161


S. Sinha,Começando o Laravel, DOI 10.1007/978-1-4842-2538-7_18
Capítulo 18-como solicitação e resposta funcionam no LaraveL 5

$this->request = $request;

$uri = $request->caminho();

var_dump($uri);

//código finalizado

Além disso temos uma rota em nosso 'routes.php', assim:

//código inicial

get('teste', 'TestController@testRequest');

//código finalizado

Agora, se formos ao nosso navegador e digitarmoshttp://localhost:8000/testeobtemos uma


resposta como esta:

string 'teste' (comprimento = 4)

Se digitarmos em nosso navegador assim: http://localhost:8000/test/hagudu/class=5/


school=Don%20Boscoe no nosso nível de rota passamos mais duas variáveis como esta:

//código inicial

get('teste/{nome}/{classe}/{escola}', 'TestController@testRequest');

//código finalizado

Obtemos uma saída como esta:

string 'teste/hagudu/class=5/escola=Don%20Bosco'

(comprimento=38)

Assim, seu usuário envia uma solicitação e nós rastreamos o caminho da URL através do nosso objeto de
solicitação. No Laravel 5 isso é feito por injeção de dependências. Discutiremos isso detalhadamente. Portanto,
se você é um iniciante, não se assuste. Parece que podemos fazer muitas coisas através deste objeto Request.
Podemos enviar alguns inputs através de um formulário e recebê-los em nosso Controller e atualizar o perfil
do Usuário. Podemos gerenciar pagamentos e muito mais.
Agora, se quisermos o caminho completo da URL, podemos digitar em nosso controlador assim:

162
Capítulo 18-como solicitação e resposta funcionam no LaraveL 5

$url = $request->url();

E a saída muda para isto:

string 'http://localhost:8000/test/hagudu/class=5/
school=Don%20Bosco' (comprimento=60)

Você obtém o URL completo em vez de apenas o caminho do URI. Existem muitos métodos de solicitação
que você achará muito úteis posteriormente. Como você ainda não iniciou o Laravel, não queremos nos
aprofundar muito. Existem alguns métodos que você pode querer saber, como este:

$nome = $request->input('nome');

Nesse caso, você obtém um nome nos campos do formulário. Você também pode obter um array e a
recuperação não é muito complexa.

$input = $request->only('nome de usuário', 'senha');


$input = $request->except('cartão_crédito');

Neste caso você obtém apenas o nome de usuário e a senha, exceto as informações do
cartão de crédito. Há muito mais exemplos, e iremos abordá-los quando chegar a hora certa.

O que significa resposta?


Basicamente, o que todas as rotas e controladores enviam de volta ao navegador é a resposta. Os
usuários enviam solicitações e o servidor devolve a resposta. O mecanismo básico é simples o suficiente para
entender o que está acontecendo nos bastidores. O Laravel pode fazer muitas coisas e está equipado com
diversas maneiras de enviar respostas.
Mas a resposta principal é uma string em uma rota como esta:

Rota::get('/', function() {

retornar 'Olá Mundo';

});

Mas esta é uma string bastante simples. O Laravel pode fazer muito mais, como retornar uma
instância 'Illuminate\Http\Response' ou uma View completa. O que significa retornar uma instância
completa de 'Resposta'? Na verdade, ele permite que você personalize o código de status HTTP e os
cabeçalhos da resposta. Uma instância 'Response' herda da classe
'Symfony\Component\HttpFoundation\Response', fornecendo uma variedade de métodos para
construir respostas HTTP. Após instalar o Laravel, se você abrir o diretório 'vendor/symfony', você não
encontrará a classe 'Symfony\Component\HttpFoundation\Response' que o Laravel herda lá. Mas se
você trabalhar individualmente e instalar componentes do 'Symfony', você encontrará essa classe.

A HttpFoundation define uma camada orientada a objetos para a especificação HTTP. Ele
fornece uma abstração para solicitações, respostas, arquivos carregados, cookies, sessões, etc.
Você não conseguirá isso dentro do Laravel, mas para seu conhecimento e compreensão, saiba
que usamos componentes do Symfony como este:

163
Capítulo 18-como solicitação e resposta funcionam no LaraveL 5

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\HttpFoundation\Response;

$request = Solicitação::createFromGlobals();

echo $request->getPathInfo();

E usamos o objeto Response assim:

$response = new Response('Not Found', 404, array('ContentType' => 'text/plain'));

$resposta->enviar();

E no Laravel basicamente retornamos uma resposta assim:

use Illuminate\Http\Response;

Rota::get('home', function() {

return (new Response($content, $status))->header('ContentType',


$value);

});

Você pode enviar uma resposta JSON como esta:

Rota::get('/', function() {

return resposta()->json(['nome' =>


'Sanjib', 'localização' => 'Plutão']);

});

E você tem uma saída como esta no seu navegador:

{"name":"Sanjib","location":"Plutão"}

Uma saída JSON pura é um formato legível por humanos. Outro bom exemplo de resposta é o
redirecionamento. Você pode usar dois métodos auxiliares para redirecionar usuários conforme necessário.
Quando você usa respostas de redirecionamento, elas são, na verdade, instâncias da classe
'Illuminate\Http\RedirectResponse'. Eles contêm os cabeçalhos adequados necessários para redirecionar o
usuário para outro URL. Existem várias maneiras de gerar uma instância 'RedirectResponse'. O método mais
simples é usar o método auxiliar global de 'redirecionamento':

Route::get('suapágina', function() {

164
Capítulo 18-como solicitação e resposta funcionam no LaraveL 5

return redirecionamento('/suapágina');

});

E também existem métodos anteriores que também já estão à mão. Se você quiser
que seu usuário preencha determinados formulários e validar isso com entrada, você pode
usar algo assim:

Route::post('seu/perfil', function() {

// Valida a solicitação

return back()->withInput();

});

Ao aprender mais sobre roteamento nomeado e ações do controlador, você pode querer
usá-los assim:

return redirecionamento()->rota('login');

Ou assim:

return redirecionamento()->action('HomeController@index');

165
CAPÍTULO 19

Contratos vs. Fachadas

Até agora você entendeu que a estrutura total do Laravel 5 depende de muitos blocos de interfaces,
classes e outras versões de pacotes que os desenvolvedores de pacotes desenvolveram até agora. O
Laravel 5 os utilizou com prazer, e eu encorajo você a fazer o mesmo seguindo o princípio SOLID e o
acoplamento fraco. Para dominar o Framework adequadamente, você precisa entender os principais
serviços que executam o Laravel 5. Quais são os principais recursos nos bastidores? Basicamente, os
contratos intervêm nesse cenário. Contratos são interfaces que fornecem esses serviços principais.
Assim como 'Illuminate\Contracts\Mail\ Mailer' define o processo de envio de e-mails e fazendo isso,
esta interface simplesmente agrupa a implementação de classes de mailer alimentadas pelo
SwiftMailer. Agora, o que são as 'Fachadas'? O título deste capítulo é 'Contratos vs. Fachadas'. Eles têm
alguma semelhança ou relacionamento ou qualquer outra coisa? Deixe-me mencionar algo sobre
Facades primeiro.
Fachadas também são interfaces. Mas eles têm uma diferença distinta dos Contratos. Em primeiro
lugar, Facades são interfaces estáticas que fornecem métodos para as classes de contêiner de serviço.
Você já viu muitas fachadas. Lembre-se de 'App', 'Route', 'DB', 'View', etc. A principal qualidade das
Fachadas é que você pode usá-las sem dicas de digitação. Como no seu arquivo 'routes.php' você pode
escrever este código:

Rota::bind('livros', function ($id){

return App\Livro::where('id', $id)->first();

});

Esta fachada 'Rota' resolve diretamente os contratos fora do contêiner de serviço. Embora Facades
sejam interfaces estáticas, elas possuem sintaxes mais expressivas e fornecem mais testabilidade e
flexibilidade do que a metodologia estática tradicional. Mas a vantagem de 'Contratos' é que você pode
definir dependências explícitas para suas classes e tornar seu aplicativo mais flexível. É claro que, para a
maioria das aplicações, as fachadas funcionam bem. Mas em alguns casos se você quiser inovar algo
mais, é necessário utilizar Contratos. Como você poderia implementar um contrato? É extremamente
simples e um exemplo pode iluminar todo o conceito. Na verdade, você já usou! Suponha que você
tenha um ‘BookController’ através do qual deseja manter uma longa lista de seus livros favoritos. Para
fazer isso você precisa armazenar livros no banco de dados. Para fazer isso, você pode primeiro vincular
seu modelo 'Book' em seu 'routes.php' e, em seguida, usando o recurso, você pode fazer todos os tipos
de operações CRUD. Para fazer isso, você precisa fazer login.

© Sanjib Sinha 2017 167


S. Sinha,Começando o Laravel, DOI 10.1007/978-1-4842-2538-7_19
Capítulo 19-Contratos vs. FaCadas

Considere este código:

armazenamento de função pública (solicitação $ solicitação)

if (Auth::check()) {

//O usuário está logado

Você pode verificar se o usuário está logado ou não. E dependendo disso você pode adicionar
apenas seus livros favoritos. Para verificar você usa a fachada 'Auth'. Isso é bom; Contanto que você
não queira um estado mais desacoplado, ele funciona muito bem. Mas se você preferir seguir o
princípio SOLID e desejar um estado mais desacoplado, em vez de depender da concreção, você deverá
adotar uma abordagem abstrata mais robusta. E nesse caso o Contract vem em seu socorro. O próprio
Taylor Otwell mantém repositórios no GitHub sobre Contratos, então é melhor você dar uma olhada.
Todos os contratos do Laravel residem lá:

https://github.com/illuminate/contracts

Agora voltemos ao nosso tópico anterior. Portanto, podemos usar nossa fachada 'Auth'. Mas
tente entender uma coisa; quando você usa fachada ela assume a estrutura e fica fortemente
acoplada a uma concretagem. Mas considerando o princípio SOLID, você deseja um estado
dissociado. O que fazer? Consideremos outro cenário. Podemos injetar nossa fachada 'Auth' através
de um construtor assim e reescrever todo o nosso código desta forma:

use Illuminate\Http\Request;

use App\Http\Requests;

use App\Http\Controllers\Controller;

use Illuminate\Auth\Guard como Auth;

classe BooksController estende o controlador

/**

* Exibir uma listagem do recurso

168
Capítulo 19-Contratos vs. FaCadas

* @return Resposta

*/

protegido $auth;

função pública __construct(Auth $auth) {

$this->auth = $auth;

armazenamento de função pública (solicitação $ solicitação)

$this>auth->tentativa();

Agora você pode opinar que é muito melhor, pois injetamos a instância 'Auth' por meio
de nosso construtor. Sim, está melhor do que antes, mas ainda falta o princípio de design
SOLID. Depende de uma classe concreta como a seguinte:

namespace Illuminate\Auth;

useRuntimeException;

use Illuminate\Support\Str;

use Illuminate\Contracts\Events\Dispatcher;

use Illuminate\Contracts\Auth\UserProvider;

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\HttpFoundation\Response;

use Illuminate\Contracts\Auth\Guard como GuardContract;

use Illuminate\Contracts\Cookie\QueueingFactory como CookieJar;

use Illuminate\Contracts\Auth\Authenticatable como UserContract;

use Symfony\Component\HttpFoundation\Session\SessionInterface;

169
Capítulo 19-Contratos vs. FaCadas

classe Guard implementa GuardContract {....}

//o código está incompleto por questões de brevidade

Como você pode ver, quando usamos esta linha de código em nosso 'BookController': use Illuminate\
Auth\Guard as Auth, na verdade injetamos uma instância baseada em concreção e não em abstração. Quando
testarmos a unidade de nosso código, teremos que reescrever nossos códigos. Além disso, sempre que você
chamar qualquer método através desta instância, ele estará ciente do seu framework. Mas precisamos de
torná-lo completamente inconsciente do nosso Quadro e tornar-nos frouxamente acoplados. Para fazer isso
basta alterar uma linha de código em nosso 'BookController'.
Em vez dessa linha de código:

use Illuminate\Auth\Guard como Auth;

Escrevemos esta linha de código:

use Illuminate\Contracts\Auth\Guard como Auth;

E é isso! Agora nossa instância 'Auth' está completamente acoplada. E agora podemos
alterar essa linha de código no método store():

if (Auth::check()) {

//O usuário está logado

para esta linha de código:

$this->auth->tentativa();

E está feito. Agora sua aplicação alcançou mais sofisticação seguindo o princípio de
design SOLID e tornando-se completamente fracamente acoplada. Finalmente, se
checássemos a interface Illuminate\Contracts\Auth\Guard, o que veríamos? Basta dar
uma olhada para entender o que acontece nos bastidores. O código dessa interface é
muito grande, então, para resumir, apenas eliminamos o método try() dela. A interface
fica assim:

namespace Illuminate\Contratos\Auth;

guarda de interface

/**

* Tentativa de autenticar um usuário usando o


dadas credenciais.

170
Capítulo 19-Contratos vs. FaCadas

* @param matriz $ credenciais

* @param bool $lembrar

* @param bool $login

* @return bool

*/

tentativa de função pública (matriz $ credenciais = [], $ lembrar = falso, $ login =


verdadeiro);

.....

//este código está incompleto

Agora seu código não está acoplado a nenhum fornecedor ou mesmo ao Laravel. Você não é obrigado a
seguir uma metodologia rígida de uma classe concreta. Você pode simplesmente implementar sua própria
metodologia alternativa em qualquer contrato.
Espero que esta comparação entre “contrato” e “fachada” faça sentido.

171
CAPÍTULO 20

Middleware, filtro de
camadas e segurança extra

HTTP Middleware é uma das melhores facilidades com as quais o Laravel 5 vem. Ele não apenas
adiciona segurança extra ao seu aplicativo, mas também oferece liberdade suficiente para criar seu
próprio mecanismo de segurança junto com o mecanismo de autenticação padrão do Laravel. Como
você já sabe, quando um usuário solicita uma página, o navegador envia a solicitação e o servidor
responde. Às vezes, esse mecanismo de solicitação e resposta é simples e às vezes bastante
complicado. Mas no final das contas, sempre que um usuário solicita uma página, uma solicitação HTTP
entra em seu aplicativo. Na maioria das vezes é inócuo, mas como diz o provérbio, você não pode e não
deve confiar na entrada ou solicitação do usuário, por isso precisa ser filtrado. Ele deve ser filtrado
quando seu aplicativo precisar de um pouco mais de autenticação ou de medidas de segurança. O
middleware faz isso imediatamente.
O Laravel 5 vem com middleware 'Autenticar'. É padrão para que você não precise ajustá-lo para
adicionar segurança extra ao seu aplicativo. O mecanismo é muito simples. Ele verifica as credenciais do
usuário e permite que ele entre no seu aplicativo e prossiga. Mas além deste Middleware padrão
podemos adicionar nossas próprias funcionalidades.
A seguir, no nível de construção ele instancia esse 'auth' para que na função handle ele
possa verificar se o usuário é um convidado ou um usuário autenticado. Uma tarefa bastante
simples, mas há algo mais. Nessa pasta, há outro arquivo: 'RedirectIfAuthenticated. php'.
Vejamos seu código também:

<?php

namespace App\Http\Middleware;

usar Fechamento;

use Illuminate\Contratos\Auth\Guard;

classe RedirectIfAuthenticated

/**

© Sanjib Sinha 2017 173


S. Sinha,Começando o Laravel, DOI 10.1007/978-1-4842-2538-7_20
Capítulo 20-Middleware, filtro de camada e segurança extra

* A implementação da Guarda.

* @var Guarda

*/

protegido $auth;

/**

* Crie uma nova instância de filtro.

* @param Guarda $auth

* @return nulo

*/

função pública __construct(Guarda $auth)

$this>auth = $auth;

/**

* Lidar com uma solicitação recebida.

* @param \Illuminate\Http\Request $request

* @param \Encerramento $próximo

* @return misto

*/

identificador de função pública ($ solicitação, Fechamento $ próximo)

174
Capítulo 20-Middleware, filtro de camada e segurança extra

if ($this->auth->check()) {

return redirecionamento('/home');

return $próximo($solicitação);

Faz quase a mesma coisa. Ele verifica a autenticação do usuário e permite que ele
vá até o local desejado. Aqui está:

1. if ($this->auth->check()) {

2. return redirecionamento('/home');

3. }

Agora, a questão é: como isso funciona imediatamente? Para descobrir nossa resposta,
precisamos ir à nossa página 'routes.php'. Aqui já vimos como podemos usar o processo de
“login, logout e registro” usando o mecanismo de autenticação padrão. Fazendo isso, tivemos
que escrever um código como este:

1. Route::group(['middleware' => 'auth'], function () {

2. Rota::get('home', function() {

3. retornar visualização('auth.home');

4. });

5.
6. Rota::get('painel', function() {

7. retornar visualização('auth.dashboard');

8. });

9.});

Você passa pela primeira linha e esperançosamente agora faz sentido com a lógica padrão
do Middleware. Em nosso Grupo de Rotas, usamos

['middleware' => 'autenticação']

175
Capítulo 20-Middleware, filtro de camada e segurança extra

E se conecta remotamente ao middleware de autenticação integrado. Na verdade, está definido


em 'app/Kernel.php' como uma propriedade protegida.

1./**

2. * O middleware de rota do aplicativo.

3. *

4. * @var matriz

5. */

6. protegido $routeMiddleware = [

7. 'autenticação' =>

\App\Http\Middleware\Authenticate::class,

8. 'auth.básico' =>
\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

9. 'convidado' =>
\App\Http\Middleware\RedirectIfAuthenticated::class,

10. ];

O funcionamento do Authenticate Middleware padrão agora está claramente compilado. Que tal
adicionar algumas funcionalidades próprias? Vimos em nosso capítulo Autenticação que um usuário faz login e
vai para o '/dashboard'. Bem, primeiro precisamos adicionar algumas funcionalidades extras em nossa tabela
de 'usuários', para que um dos usuários seja o administrador e somente ela possa entrar em uma página de
'blog'.
Como precisamos testar nosso próprio Middleware no Laravel, decidimos torná-lo o mais simples.
Portanto, mantemos um link para a página do 'Blog' em nossa página 'Painel'. Agora cada usuário faz
login e clica nesse link. Mas nosso Middleware irá verificar se aquele usuário é administrador ou não.
Se ela for administradora, poderá acessar a página 'Blog' com poder administrativo especial e, se não
for, será enviada de volta à página inicial para usuários em geral. Esta é a nossa etapa processual de
construção de middleware de administrador simples. Deixe-nos começar.

Primeiro, precisamos configurar uma coluna extra na célula da tabela 'usuários'. Precisamos migrar para isso.
Você pode fazer isso manualmente em seu PHPMyAdmin ou usar diretamente o Tinker para adicionar essa coluna. Mas
a migração é mais simples.
Abra o terminal, acesse nossa aplicação Laravel e emita este comando:

php artesão make:migração add_is_admin_to_user_table –table=users

176
Capítulo 20-Middleware, filtro de camada e segurança extra

Vá para a pasta ‘database’ e veja se sua nova migração foi criada. Agora, antes de
iniciar a migração, precisamos ajustar os métodos up() e down() assim:

1. <?php

2.

3. use Illuminate\Database\Schema\Blueprint;

4. use Illuminate\Database\Migrations\Migration;

5.

6. classe AddIsAdminToUserTable estende migração

7. {

8. /**

9. * Execute as migrações.

10. *

11. * @return nulo

12. */

13. função pública ativa()

14. {

15. Schema::table('usuários', function (Blueprint $tabela) {

16. $table->boolean('is_admin')->default(false);

17. });

18. }

19.

20. /**

21. * Reverter as migrações.

22. *

177
Capítulo 20-Middleware, filtro de camada e segurança extra

23. * @return nulo

24. */

25. função pública para baixo()

26. {

27. Schema::table('usuários', function (Blueprint


$tabela) {

28. $table->dropColumn('is_admin');

29. });

30. }

31.

Agora estamos prontos para migrar, então emita este comando:

php artesão migrar

Verifique sua tabela de 'usuários'; você verá que uma coluna extra já foi adicionada e cada uma delas é
falsa. Então você escolhe qualquer usuário e torna-o administrador para que quando verificarmos a
autenticação ela seja verdadeira. Nossa configuração de banco de dados está pronta. Agora podemos
prosseguir para a próxima etapa. Esta etapa envolve a criação de nossa própria lógica de Middleware que irá
verificar se o usuário é administrador ou não. Se ela for a administradora, ela poderá acessar a página ‘Blog’.
Caso contrário, ela será enviada de volta à página inicial para usuários em geral. Podemos criar nosso
Middleware customizado através do console. Em nosso terminal, emitimos este comando:

php artesão make:middleware RoleMiddleware

Como você pode ver, chamamos nosso Middleware de 'RoleMiddleware'. Você pode nomeá-lo de
forma diferente. Sem problemas. Ele responderá imediatamente com um prompt informando que seu
middleware foi criado com sucesso. Vamos para a pasta 'app/Http/Middleware' e verificar. Sim, foi
criado. Ele vem com um método handle() como de costume. Agora tudo o que precisamos é adicionar
primeiro esta linha de código no topo da página:

use Illuminate\Contratos\Auth\Guard;

Precisamos verificar a autenticidade do usuário. O código completo fica assim:

1.<?php

178
Capítulo 20-Middleware, filtro de camada e segurança extra

2.

3. namespace App\Http\Middleware;

4. use Fechamento;

5. use Illuminate\Contratos\Auth\Guard;

6. use Illuminate\Http\RedirectResponse;

7. //usar Aplicativo\Usuário;

8.

9. classe RoleMiddleware

10.

11. protegido $auth;

12.

13. função pública __construct(Guarda $auth) {

14. $this->auth = $auth;

15. }

16.

17.

18. /**

19. * Lidar com uma solicitação recebida.

20. *

21. * @param \Illuminate\Http\Request $request

22. * @param \Encerramento $próximo

23. * @return misto

24. */

179
Capítulo 20-Middleware, filtro de camada e segurança extra

25. identificador de função pública ($ solicitação, Fechamento $ próximo)

26. {

27. if ($this->auth->check())

28. {

29. if ($this->auth->user()->is_admin == TRUE)

30. {

31. return $próximo($solicitação);

32. }

33. }

34.

35. devolver novo

RedirectResponse(url('/auth/login'));
36. }
37.

38.}

As linhas 27 e 29 são muito importantes; na verdade, em última análise, ele desempenha um papel crucial em nosso
próprio Middleware.
A lógica é bastante simples. Nossa classe 'RoleMiddleware' é chamada sempre que uma instância
de 'Guard' é criada e isso cuidará do processo de autenticação adicional. Então no nosso método
handle() que passa dois parâmetros, 'request' e 'Closure $next', vamos adicionar alguns temperos
extras para que quando ele verificar as credenciais do usuário, ele procure e pergunte se ela é a
administradora. Caso contrário, ela será enviada de volta à página de login. Portanto, se alguém
digitar a URL e tentar entrar na página do nosso 'Blog', ela será enviada de volta para a página de
login. Agora, se ela for uma usuária registrada, ela pode fazer login, mas acaba na página ‘Dashboard’.
Para facilitar este 'RoleMiddleware' precisamos adicionar um Route Group extra em nosso 'routes. php'
assim:

1. Route::group(['middleware' => 'auth'], function () {

2. Rota::get('home', function() {

3. retornar visualização('auth.home');

4. });

180
Capítulo 20-Middleware, filtro de camada e segurança extra

5.

6. Rota::get('painel', function() {

7. retornar visualização('auth.dashboard');

8. });

9. });

10.

Rota::group(['middleware' => 'role'], função ()

11.

12. Rota::get('blog', function() {

13. return view('blog.index');

14. });

15.

16. });

Você vê na linha 10, adicionamos um Middleware de Grupo de Rota extra, 'role'. Mas a questão é
como nosso aplicativo aprenderá sobre isso. Ok, nossos passos foram incompletos até agora.
Precisamos registrá-lo em 'app/Kernel' para que o código 'app/Kernel.php' fique assim:

1. $routeMiddleware protegido = [

2. 'auth' => \App\Http\Middleware\Authenticate::class,

3. 'auth.basic' => \Illuminate\Auth\Middleware\


AuthenticateWithBasicAuth:

:aula,

4. 'convidado' => \App\Http\Middleware\RedirectIfAuthenticated::class,

5. 'iplog' => \App\Http\Middleware\RequestLogger::class,

6. 'role' => \App\Http\Middleware\RoleMiddleware::class,

7. ];

181
Capítulo 20-Middleware, filtro de camada e segurança extra

Cuidado com a linha 6. Registramos nosso

'role' => \App\Http\Middleware\RoleMiddleware::class,

E agora funcionará como uma brisa. Os próximos passos são deixados para criar uma página
Controller e View. Isso você pode fazer. No próximo capítulo lançaremos oficialmente um recurso de
administrador e criaremos um painel administrativo onde um administrador pode criar, editar e excluir
usuários.
Até agora você viu como podemos controlar o acesso aos usuários usando vários tipos de
Middleware. Use sua imaginação para construir todo o Middleware maluco, e o procedimento é
bastante simples. Você pode lidar com isso sozinho. Suponha que queiramos verificar os pontos que os
usuários ganharam em um fórum. Podemos fazer algumas tarefas mais estranhas, como verificar se o
nome de um usuário começa com alguma letra específica, etc. Podemos usar o middleware 'antes' e
'depois' para que nosso aplicativo lide com algo antes e execute algo depois.

Suponha que queiramos verificar os pontos do fórum de um usuário. Podemos criar um Middleware
assim:

1. namespace App\Http\Middleware;

2.

3. usar Fechamento;

4.

5. classe PointMiddleware

6. {

7. /**

8. * Execute o filtro de solicitação.

9. *

10. * @param

\Illuminate\Http\Request $request

11. * @param \Closure $próximo

12. * @return misto

13. */

14. identificador de função pública ($ solicitação, Fechamento $ próximo)

182
Capítulo 20-Middleware, filtro de camada e segurança extra

15. {

16. if ($request->input('ponto') <= 500) {

17. return redirecionamento('home');

18. }

19.

20. return $próximo($solicitação);

21. }

22.

23.

Agora também podemos lidar com isso antes e depois assim:

1. namespace App\Http\Middleware;

2.

3. usar Fechamento;

4.

5. classe AntesMiddleware

6. {

7. identificador de função pública ($ solicitação, Fechamento $


próximo)

8. {

9. // Executar a ação

10.

11. return $próximo($solicitação);

12. }

13. }

183
Capítulo 20-Middleware, filtro de camada e segurança extra

14.

namespace App\Http\Middleware;

15.

16. usar Fechamento;

17.

18. classe AfterMiddleware

19. {

20. identificador de função pública ($ solicitação, Fechamento $


próximo)

21. {

22. $resposta = $próximo($solicitação);

23.

24. // Executar a ação

25.

26. retornar $resposta;

27. }

28. }

Portanto, há muitas ações esperando para serem exploradas nesta seção de Middleware.
Concluiremos com um Middleware de logging que registrará todas as solicitações que chegam à sua
aplicação: muito simples e elegante. Você aprendeu como criar um Middleware. Portanto, crie
primeiro um middleware 'IPLogger'. E adicione uma linha de código em seu método handle() assim:

1. <?php

2.

3. namespace App\Http\Middleware;

184
Capítulo 20-Middleware, filtro de camada e segurança extra

4.

5. use Fechamento;

6.

7. classe IPLogger

8. {

9. /**

10. * Lidar com uma solicitação recebida.

11. *

12. * @param \Illuminate\Http\Request $request

13. * @param \Encerramento $próximo

14. * @return misto

15. */

16. identificador de função pública ($ solicitação, Fechamento $ próximo)

17. {

18. \Log::info($request->getClientIp());

19. return $próximo($solicitação);

20. }

21.

Em seguida, em seu 'routes.php', adicione este grupo de middleware:

1. Rota::get('/', ['middleware' => 'iplog', função ()

2. return view('índice');

3. }]);

185
Capítulo 20-Middleware, filtro de camada e segurança extra

Para que cada vez que um usuário enviar uma solicitação para a página de índice, seu 'endereço
IP' seja armazenado em 'storage/logs/laravel.log' assim:

1. [20150822 18:16:14] local.INFO: ::endereçoipad

2. [20150822 18:16:55] local.INFO: ::endereçoipad

Devo mencionar que você deveria ter registrado seu 'IPMiddleware' em 'app/Http/
Kernel.php' assim:

'iplog' => \App\Http\Middleware\IPLogger::class,

E está feito!
Por favor, dê uma olhada na documentação para obter informações mais valiosas, como
parâmetros de middleware e Middleware terminável, onde você inicia uma sessão, que é
armazenada e encerrada após a conclusão de sua tarefa.

186
Índice

„„ A Classe de controlador, 29
controlador, 35
Abstração, 18 Contêiner IoC e interface, 35
Funções anônimas, 28 Autenticação camadas, 29
e autorização, 81 Arquivo MyController.php, visualização de
AuthController, 81–84 página 30–31, 31
config/app.php, 81 camada de apresentação, 29
arquivo de banco de dados/ controlador engenhoso, 34
migração, 85 login.blade.php, 85–86, RESTful, 32
88–89 opção de logout, 89–90 papel de, 33
método validador(), 84 Arquivo rotas.php, 29–30
Falsificação de solicitação entre sites (CSRF), 25

„„ B CRUD (criar, recuperar, atualizar, excluir)


aplicação, 59
Lâmina.VerVisualizações e lâmina método controlador, 70
create.blade.php, 74–76 criação

„„ C (página de revisão), 74 página


de edição, 77, 79
Compositor página editreview.blade.php, 76
centralmente/globalmente, 2 página index.blade.php, página de
comandos, 2–3 índice 70–72, 79
tipo de arquivo, 3 visualização de página, 76

globalmente, 4 página de revisão, 70, 72


página inicial, 1 arquivo review.php, 68
instalação do Laravel 5.3, 4 Arquivo rotas.php, 73, 76
conexão com a Internet, 4 show.blade.php, 73
Laravel5.2,3 arquivo table.php, 67–68
localmente, 2 Arquivo TaskController.php, 68, 69, 72, 74
pacote monólogo, 3 função url, 72
página inicial, 1–2
Contratosvs.Fachadas
método tentativa(), 170 „„ D
Método BookController, 170 Migração de banco de dados, 49
operações CRUD, 167 vantagem, 49
interfaces, 167 . arquivo env, 49
Princípio SOLID, 168–169 comando de migração, 51
método store(), 170 Arquivo PHP, 50–51

© Sanjib Sinha 2017 187


S. Sinha,Começando o Laravel, DOI 10.1007/978-1-4842-2538-7
- ÍNDICE

Migração de banco de dados (cont.) Usuário.php, 125–126


ferramenta phpMyAdmin, 52 Método var_dump(), 135–136
tabela de tarefas, 50

„„ F, G
função para cima e para baixo, tabela
de 50 usuários, 49
Fachadas, 167

„„ E Estrutura de arquivo

pasta do aplicativo, 15

Relações eloquentes pasta de inicialização, 16


vantagem de, 128 pasta de banco de dados, 16

método pertenceTo(), 141 página inicial, 17


método chunk(), 133 instalação, 16
aula de contato, 126–127 interfaces e método, 19
método contato(), 140 Laravel 5.3.18, 15
detalhes de contatos, 131–132 pasta pública, 16
tabela de contatos, 129 Princípio de design SOLID, 17
criação, 53 Formulários, 65
ponto crucial de, 132 matriz de aliases, 65
tabela de tarefas de banco de dados, 57, matriz de provedores, 65
124 definição, 123
classe vazia, 56
código-fonte final, 137, „„ H
139 função(), 129 Herdade
Método hasMany(), 143–144 pasta e seção do site, 11 arquivo
método hasOne(), 139, 143 Homestead.yaml, 10 instalação e
inserir, atualizar/excluir, 133–134 configuração, 10 test.app, 13
interface, 54
Formato JSON e Caixa Vagrant e Vagrant, 9
saída, 128 comando vagrant up, 12
atribuição em massa, 56, 127

„„ Eu, J, K
classe modelo, 53
Método NewUser, 134, 142–143
ORM, 123 Interfaces e injeção de método, 19
resultado de saída, 129–131

„„ eu
Arquivo PHP, 53
tabela de postagens, 144–145

propriedades, 127, 136 Casa Laravel, 7


método role(), 149–150
tabela role_user, 145–149
rotas.php, 125, 140, 151 „„ M
método save(), 54–55 Middleware, filtro de camada e
serialize() e unserialize() segurança, 173
métodos, 129 arquivo app/Kernel.php, 176, 181
Instrução SQL, 141 autenticação, 173
criação de tabelas, 123 página do blog, 176
tabela de tarefas, 54 nível de construção, 173
tipos de, 123 método handle(), 178–180, 184–185
método update(), 55 middleware, 182–184
classe de usuário, 124–125 RedirectIfAuthenticated.php, 173

188
- ÍNDICE

FunçãoMiddleware, 178
Arquivo Routes.php, 175, 180–181, 185
„„ S, T, U
storage/logs/laravel.log, 186 Método up() e Segurança e autenticação, 153
down(), 177–178 Modelo, visualização, Autorização, 158–159

controlador e fluxo de trabalho, 59 página de índice, 158

método all(), 60 método make(), 154


Arquivo rotas.php, 59 Método NewUser, 153
página task.blade.php, 61 arquivo método password_hash(), tabela
TaskController.php, 60 classe de password_reminder 154, 153
modelo de tarefa, 60 rotas.php, 157–158
Metodologia ModelViewController, 123 Tabela de modelo de usuário, 155–
157 método var_dump, 155
Princípio de design SOLID, 17
„„ NÃO banco de dados SQLite, 63
Rotas nomeadas, 26 arquivo banco de dados.sqlite, 64 .

arquivo env, 63

„„ P, Q caminho do arquivo, 63

Método estático.VerRoteamento
PHP 5, 19

„„ V W X Y Z
„„ R Vagabundo,7.Veja tambémValidação de
Estado Representacional propriedade
Transferência (REST), 32 ação.php, 96
Solicitar regras condicionais, 112–113
significado, 161 validação personalizada, 113–118
saída, 163 mensagens de erro, 104–107
TestController, caminho variável $error, 109
URI 161–162, 163 formulário, 91-92
Controlador engenhoso, validação, 119–120, 122
método de resposta 34 visualizar página, 93
componentes, 163 significado, 91
método auxiliar, 164-165 Classe MyCustomValidation, 117
JSON, 164 parâmetros, 105
significado, 163 Register.blade.php, 108–109
saída, 164 arquivo Registration.blade.php, 92
Função de rota(), 163 regras, 110–112
função returnASimplePage, 30 código-fonte, 97–103
Roteamento, 21 Classe valid.php, 94–95
funções anônimas, 21, 28 visualizações e lâmina
método any(), 25 Arquivo about.blade.php, 43, 44
arquivo app/Http/routes.php, 21 método compacto, 45
melhores práticas, 25 Código de estilo CSS, 42 dados
conceito, 28 passados dinamicamente, 46
Estilo CSS, 22 código master.blade.php, 41
Código HTML, 22 código MyController, 45
Protocolo HTTP, 21 processo, 41
métodos, 24 Caixa virtual, 7
rotas nomeadas, 26 seção de download, 8
organizar arquivos, 27 instalação, 7
Arquivo rotas.php, 21, 24 Kali Linux e Windows XP, 9
navegador da web, 23 software UBUNTU, 8

189

Você também pode gostar