Salvando imagens no Laravel 5.5

Victor Hugo Rocha
Training Center
Published in
4 min readOct 27, 2017

Olá, DevZ.

Já teve dificuldade em salvar seus arquivos em um projeto? Problemas com permissão? Anda duplicando o código em vários lugares do projeto? Bem, você deve estar sentindo que isso não está muito certo, pelo menos você deveria. Vamos resolver isso agora aplicando o conceito de Repository Pattern no seu projeto Laravel.

Primeiro vamos entender porque duplicar a sua lógica no código é um problema em potencial. Duplicar sua lógica aumenta exponencialmente a possibilidade de erros na sua aplicação, dificulta a centralização da sua regra de negócio e te incapacita de testar facilmente uma funcionalidade do seu sistema.

O Repository Pattern é um padrão de projeto(Design Pattern) importante que abstrai a sua lógica de persistência de dados. Isso significa centralizar sua regra de negócio, facilitando que você teste e replique uma funcionalidade que é utilizada mais de uma vez dentro do seu sistema.

Para se aprofundar mais no assunto recomendo esse ótimo texto do Vinicius Reis.

O primeiro passo para salvar a sua imagem é criar um formulário. Básico do básico mas vamos lá. Informar o method como POST, na action você passa a sua rota de salvar o produto e o atributo html enctype="multipart/form-data". Ele diz como os dados do formulário devem ser codificados ao serem enviados para o servidor, esse atributo só pode ser usado com o método post. Esse atributo deve ser usado sempre que você estiver subindo o arquivo no seu formulário.

Um botãozinho de enviar e é isso aí. Beleza, Victor mas e esse {{ csrf_field() }} aí depois da tag form? Tá na mão a melhor explicação possível: a documentação.

O segundo passo é preparar a nossa função na Controller. Vou entender que você já criou a sua rota, deu o mesmo nome que chamou na action do seu formulário. Se você ficou um pouquinho perdido pode dar uma olhada nesse artigo que eu escrevi e voltar aqui quando terminar. Nele eu abordo todo esse fluxo.

Nossa função store recebe a Request onde se encontra todos os inputs do formulário e importa o nosso repositório de imagens ImageRepository, já vamos chegar nele, antes disso nós usamos todos os inputs do formulário para criar o produto com exceção da imagem, que vai passar pela função que criamos no nosso repositório. Chamamos ela com $repo->saveImage($args[])

Verificamos se uma imagem foi enviada no formulário, caso seja verdadeiro, chamamos a nossa função que se encontra no ImageRepository e passamos vários parâmetros para ela, você pode simplificar a sua função se você quiser, é mais importante entender o conceito aplicado nessa funcionalidade. No próximo gist vou explicar melhor os parâmetros passados.

Essa é a estrela do artigo. O primeiro passo é verificar se a variável $image enviada é nula. É nessa variável que está a imagem do nosso formulário do começo do artigo. Caso a variável esteja nula nós tratamos o erro utilizando um placeholder previamente colocado na nossa public/images.

Da imagem nós extraímos o arquivo e a extensão, geramos um nome aleatório e indicamos o destino do nosso arquivo. A variável $type é responsável por dizer a pasta em que vamos colocar a imagem. No nosso exemplo ela é referente a produto mas poderia ser a imagem do usuário, tanto faz, todas as imagens passam por essa função que centralizada a nossa lógica.

Com a variável $id nós criamos uma pasta com o id do produto, assim para cada imagem uma pasta referente ao id será criada no futuro e lá ficarão as imagens daquele produto, que pode possuir mais de uma imagem, eu só abstrai essa lógica para diminuir a função.

Na variável $url que foi criada dentro da função nós usamos $SERVER['HTTP_HOST'] para pegarmos onde estamos rodando a função, ela funciona tanto localmente como em produção. Assim localmente as imagens são servidas como localhost exatamente na porta em que você está usando e em produção as imagens usam o domínio do seu servidor. Assim você não precisa alterar nada caso ao final do projeto precise alterar o seu domínio/servidor.

Se o nosso destino não existe, nós o criamos e damos a permissão necessária para que as imagens sejam consumidas e visualizadas no sistema. Note que não estamos salvando a imagem no Banco de dados. Vamos retornar apenas a url da função. A imagem é colocada na public, assim salvamos no banco apenas o caminho para a imagem.

Utilizei o IntervationImage para manipular a imagem, usamos a variável $size para definirmos dinamicamente o tamanho das imagens, assim os produtos podem ter um tamanho diferente da foto de perfil do usuário, por exemplo, não tem problema, podemos passar ambas pela mesma função.

Após isso a imagem é salva e retornarmos para o nosso controller apenas o caminho absoluto daquela imagem, que se encarrega de salvar a informação no banco. Terminamos!

Se você chegou até aqui não esqueça de deixar o seu clap e/ou um comentário. Se você tem interesse por Laravel ou gostou do meu texto você pode ler algum dos meus outros artigos, eu recomendo:

  1. PHP — Implementando adminLTE no Laravel
  2. PHP — Criando um CRUD com Laravel
  3. PHP — Relacionando Models e Tabelas no Laravel
  4. PHP — Escrevendo o seu primeiro teste no Laravel
  5. PHP — Atualizando a versão do Laravel para 5.5

See you, Space Cowboy!

--

--