Tutorial Laravel para iniciantes
O que รฉ o Laravel?
Laravel รฉ uma estrutura MVC da web de cรณdigo aberto para PHP. Laravel รฉ uma estrutura robusta que fornece fรกcil desenvolvimento de aplicaรงรตes web PHP com recursos como um sistema de empacotamento modular com um gerenciador de dependรชncias dedicado, acesso a bancos de dados relacionais e outros utilitรกrios para implantaรงรฃo e manutenรงรฃo de aplicaรงรตes.
Laravel foi criado por Taylor Otwell. Desde o seu lanรงamento inicial em junho de 2011 (versรฃo 1), ele tem crescido cada vez mais popular no setor de frameworks PHP da indรบstria de desenvolvimento web. Grande parte dessa popularidade pode ser atribuรญda aos muitos recursos voltados para o desenvolvedor que vem com o estoque.
Por que Laravel?
Por volta de 2000, a maior parte Cรณdigos PHP era processual e podia ser encontrado na forma de โscriptsโ que teriam uma confusรฃo emaranhada de cรณdigo espaguete. Mesmo as pรกginas mais simples nรฃo tinham separaรงรฃo de preocupaรงรตese, portanto, era bastante fรกcil para um aplicativo se transformar rapidamente em um pesadelo de manutenรงรฃo. O mundo precisava de algo melhorโฆ Digite o PHP versรฃo 5 e uma variedade de estruturas PHP tentando trazer a resoluรงรฃo necessรกria e melhores soluรงรตes para vรกrios problemas de aplicativos da web.
Desde entรฃo, vimos muitos frameworks lanรงados que abririam caminho para os frameworks populares existentes e empregados hoje. Hoje, os trรชs primeiros seriam (em nossa opiniรฃo) Zend Framework, Symfony e, claro, Laravel. Embora cada uma dessas estruturas tenha sido fundada em princรญpios semelhantes e seja voltada para resolver (basicamente) os mesmos problemas comuns, suas principais diferenรงas residem em suas implementaรงรตes. Cada um deles tem suas prรณprias peculiaridades sobre como resolver problemas. Ao observar o cรณdigo produzido por cada um deles, vocรช verรก que hรก uma linha bastante sรณlida que os separa um do outro. Na nossa humilde opiniรฃo, o framework Laravel รฉ o melhor.
Saiba mais sobre o Diferenรงa entre Laravel e CodeIgniter
Como baixar e instalar o Laravel com Composer
NOTA Presume-se que vocรช jรก tenha uma cรณpia do PHP instalada em seu sistema local. Caso contrรกrio, vocรช pode ler como instalรก-lo aqui.
Composer รฉ um gerenciador de pacotes e dependรชncias. Para instalรก-lo, abra um terminal e faรงa cd em um novo diretรณrio. Execute este comando:
curl -Ss getcomposer.org/installer | php
Os resultados deste comando serรฃo assim:
Observaรงรฃo Para instruรงรตes mais extensas sobre como configurar o Laravel, consulte a documentaรงรฃo do Laravel aqui..
Vocรช o verรก baixando e compilando o script compositor.phar, que รฉ o que usamos para instalar o Laravel. Embora existam inรบmeras maneiras de configurar uma nova aplicaรงรฃo Laravel, faremos isso atravรฉs do script Laravel Composer. Para instalar este script, execute:
composer global require laravel/installer
Que serรก parecido com isto:
Isso farรก o download e instalarรก todos os arquivos da estrutura, bem como todas as dependรชncias necessรกrias. Os pacotes serรฃo salvos no diretรณrio do fornecedor. Depois de baixado e instalado, รฉ tรฃo fรกcil quanto emitir o seguinte comando:
laravel new uploadApp
Vocรช verรก algo como a seguinte saรญda:
O Composer estรก instalando todos os pacotes que o Laravel precisa para rodar. Pode demorar alguns minutos, entรฃo seja paciente. Apรณs terminar, execute um comando ls -al para ver o que foi instalado.
Aqui estรก uma breve anรกlise dos diretรณrios em um aplicativo Laravel comum:
- aplicativo/ : Esta รฉ a pasta de origem onde reside o cรณdigo do nosso aplicativo. Todos os controladores, polรญticas e modelos estรฃo dentro desta pasta
- inicializaรงรฃo/ : Contรฉm o script de inicializaรงรฃo do aplicativo e alguns arquivos de mapa de classes
- configuraรงรฃo/ : Contรฉm os arquivos de configuraรงรฃo do aplicativo. Geralmente, eles nรฃo sรฃo modificados diretamente, mas dependem dos valores configurados no arquivo .env (ambiente) na raiz do aplicativo
- base de dados/ : Abriga os arquivos de banco de dados, incluindo migraรงรตes, sementes e fรกbricas de teste
- pรบblico/ : Pasta acessรญvel publicamente contendo ativos compilados e, claro, um arquivo index.php
- recursos/ : Contรฉm ativos de front-end, como arquivos javascript, arquivos de linguagem, arquivos CSS/SASS e todos os modelos usados โโno aplicativo (chamados de modelos blade)
- rotas/ : Todas as rotas do aplicativo estรฃo aqui. Existem alguns โescoposโ diferentes de rotas, mas o que iremos focar รฉ o arquivo web.php
- armazenar/ : Todos os arquivos de cache temporรกrios usados โโpelo aplicativo, arquivos de sessรฃo, scripts de visualizaรงรฃo compilados e arquivos de log
- testes/ : Contรฉm arquivos de teste para o aplicativo, como testes unitรกrios e testes funcionais.
- fornecedor/ : Todos os pacotes de dependรชncia instalados com o compositor
Agora, vamos construir o resto do aplicativo e executรก-lo com um comando artesanal especial (para evitar o incรดmodo de instalar e configurar um servidor web como Apache ou nginx). O arquivo .env contรฉm todos os valores de configuraรงรฃo que os arquivos no diretรณrio /config usam para configurar o aplicativo. Dentro dele vocรช notarรก o valor de configuraรงรฃo de diversos parรขmetros utilizados pelo interior da aplicaรงรฃo.
Design do aplicativo: um rรกpido resumo de nossos requisitos
Neste tutorial online do Laravel, estaremos construindo um aplicativo muito simples que farรก apenas duas coisas:
- lidar com uploads de arquivos de um formulรกrio da web
- exibindo os arquivos carregados anteriormente em uma pรกgina diferente.
Para este projeto, nosso aplicativo serรก somente gravaรงรฃo, o que significa que o usuรกrio sรณ poderรก gravar arquivos e visualizar a lista de arquivos que carregou. Este aplicativo รฉ extremamente bรกsico, mas deve servir como uma boa prรกtica para vocรช comeรงar a desenvolver suas habilidades e conhecimentos em Laravel. Observe que, por uma questรฃo de brevidade, excluรญ qualquer modelagem de banco de dados, migraรงรตes e autenticaรงรฃo, mas, em uma aplicaรงรฃo do mundo real, essas sรฃo coisas adicionais que vocรช deve considerar.
Aqui estรก uma lista de componentes que precisaremos para fazer o aplicativo funcionar conforme o esperado:
- A estrada que permitirรก que o mundo externo (internet) use o aplicativo, bem como especifique o endpoint que apontarรก para onde estรก localizada a lรณgica para salvar o arquivo carregado
- A controlador que lida com a solicitaรงรฃo para o fluxo de resposta
- A modelo que serรก usado para exibir uma lista de arquivos enviados anteriormente e o prรณprio formulรกrio de upload
- A solicitar que o controlador usarรก para validar os dados transmitidos do formulรกrio web
O que รฉ uma rota?
Uma rota no Laravel รฉ basicamente um endpoint especificado por um URI que atua como um โponteiroโ para alguma funcionalidade oferecida pela aplicaรงรฃo. Mais comumente, uma rota simplesmente aponta para um mรฉtodo em um controlador e tambรฉm determina quais mรฉtodos HTTP sรฃo capazes de atingir esse URI. Uma rota nem sempre significa mรฉtodo de controlador; ele poderia simplesmente passar a execuรงรฃo do aplicativo para um fechamento definido ou uma funรงรฃo anรดnima tambรฉm.
Por que usar o Rota?
As rotas sรฃo armazenadas em arquivos na pasta /routes dentro do diretรณrio raiz do projeto. Por padrรฃo, existem alguns arquivos diferentes correspondentes aos diferentes โladosโ da aplicaรงรฃo (โladosโ vem da metodologia de arquitetura hexagonal). Eles incluem:
- web.php As rotas baseadas em โnavegadorโ voltadas para o pรบblico. Estes sรฃo os mais comuns e sรฃo os que sรฃo atingidos pelo navegador. Eles sรฃo executados no grupo de middleware da web e tambรฉm contรชm recursos para proteรงรฃo csrf (que ajuda na defesa contra ataques maliciosos e hacks baseados em formulรกrios) e geralmente contรฉm um certo grau de โestadoโ (com isso quero dizer que eles utilizam sessรตes)
- api.php Rotas que correspondem a um grupo de APIs e, portanto, possuem o middleware da API habilitado por padrรฃo. Essas rotas nรฃo tรชm estado e nรฃo possuem sessรตes ou memรณria de solicitaรงรฃo cruzada (uma solicitaรงรฃo nรฃo compartilha dados ou memรณria com nenhuma outra solicitaรงรฃo โ cada uma รฉ autoencapsulada).
- console.php Essas rotas correspondem a comandos artesanais personalizados que vocรช criou para seu aplicativo
- canais.php Registra rotas para transmissรฃo de eventos
O arquivo chave com o qual se preocupar neste momento รฉ aquele especรญfico do navegador, web.php . Jรก existe uma rota definida por padrรฃo, que รฉ aquela que vocรช acertou ao navegar atรฉ a raiz web da sua aplicaรงรฃo (a raiz web estรก no diretรณrio pรบblico). Precisaremos de trรชs rotas diferentes para que nosso aplicativo de upload funcione:
- /upload Este serรก o URI da pรกgina principal que exibe nosso formulรกrio web para upload de arquivos.
- /process Este serรก o local onde o formulรกrio localizado no URI /upload postarรก os dados enviados pelo formulรกrio (a โaรงรฃoโ do formulรกrio)
- /list Isso listarรก todos os arquivos enviados para o site
nota O endpoint /list pode nรฃo ser necessรกrio se quisermos colocar toda a lรณgica para exibir o formulรกrio de upload e a lista de arquivos em uma รบnica pรกgina, no entanto, os mantivemos separados por enquanto para adicionar um pouco mais de assunto ao assunto em questรฃo .
//inside routes/web.php
Route::get('/upload', 'UploadController@upload')->name('upload');
Route::get('/download, 'UploadController@download)->name(โdownload');
Route::post('/process', 'UploadController@process')->name('process');
Route::get('/list', 'UploadController@list')->name('list');
Neste tutorial do framework Laravel, para cada rota desejada, iremos listรก-la explicitamente no arquivo de rotas web.php usando um dos mรฉtodos de solicitaรงรฃo especรญficos de HTTP disponรญveis (get(), post(), put() , delete(), patch() ou opรงรตes() ). Para uma anรกlise de cada um deles, verifique esse fora. O que esses mรฉtodos fazem รฉ especificar quais verbos HTTP tรชm permissรฃo para acessar determinada rota. Se vocรช precisar que uma rota seja capaz de aceitar mais de um verbo HTTP (o que pode ser o caso se vocรช estiver usando uma รบnica pรกgina para exibir os dados iniciais e postar os dados do formulรกrio enviado), vocรช pode usar o mรฉtodo Route::any( ) mรฉtodo.
O segundo argumento para os mรฉtodos Route::get() e Route::post() (e qualquer outro mรฉtodo relacionado ao verbo HTTP na fachada Route), รฉ o nome de um controlador especรญfico e mรฉtodo alojado dentro dele. controlador que รฉ executado ao atingir o endpoint da rota com a solicitaรงรฃo HTTP permitida (GET, POST, PATCH, etc.). Estamos usando o UploadController para todas as trรชs rotas e as especificamos da seguinte maneira:
O รบltimo mรฉtodo que chamamos em cada rota รฉ a funรงรฃo name(), que aceita uma รบnica string como argumento e รฉ usada para โmarcarโ mais ou menos uma rota especรญfica com um nome fรกcil de lembrar (em nossos casos, carregar, processar e listar). Sei que nรฃo parece um recurso tรฃo bom dar a cada rota seu prรณprio nome quando o URL tem exatamente o mesmo nome, mas รฉ realmente รบtil quando vocรช tem uma rota especรญfica como /users/profile/dashboard/config, que seria mais fรกcil de lembrar como profile-admin ou user-config.
Uma nota sobre fachadas:
- As fachadas fornecem uma interface โestรกticaโ para classes que estรฃo disponรญveis no contรชiner de serviรงo da aplicaรงรฃo.โ
- Eles fornecem uma sintaxe concisa e memorรกvel que permite usar os recursos do Laravel sem lembrar nomes longos de classes que devem ser injetados ou configurados manualmente.
Nas definiรงรตes de rota acima neste tutorial do framework Laravel, usamos a fachada Route em vez de instanciar manualmente um novo objeto Illuminate/Routing/Router e chamar os mรฉtodos correspondentes nesse objeto. ร apenas um atalho que economiza digitaรงรฃo. Fachadas sรฃo muito usadas em todo o framework Laravel โ vocรช pode e deve se familiarizar mais com elas. A documentaรงรฃo para Fachadas pode ser encontrada aqui..
O que รฉ um Controlador?
Um controlador รฉ o โCโ na arquitetura โMVCโ (Model-View-Controller), na qual o Laravel รฉ baseado. O trabalho de um controlador pode ser resumido nesta definiรงรฃo simples: Ele recebe a solicitaรงรฃo do cliente e retorna uma resposta ao cliente. Esta รฉ a definiรงรฃo bรกsica e tambรฉm os requisitos mรญnimos de qualquer controlador. O que ele faz entre essas duas coisas รฉ geralmente considerado como a โaรงรฃoโ do controlador (ou a โimplementaรงรฃo da rotaโ). Ele atua como o segundo ponto de entrada da aplicaรงรฃo (sendo o primeiro a solicitaรงรฃo) para o cliente, que envia o payload da solicitaรงรฃo (que veremos a seguir) para a aplicaรงรฃo, esperando algum tipo de resposta (na forma de um pรกgina de sucesso, redirecionamento, pรกgina de erro ou qualquer outro tipo de resposta HTTP).
Um controlador faz (basicamente) a mesma coisa que uma definiรงรฃo de rota com uma funรงรฃo anรดnima definida como a โaรงรฃoโ quando essa rota รฉ atingida. A diferenรงa รฉ que um controlador suporta bem a separaรงรฃo de interesses enquanto uma rota รฉ definida em linha com a definiรงรฃo de URL real, o que basicamente significa que estamos acoplando o URI atribuรญdo ร rota com a implementaรงรฃo da rota, ou o cรณdigo que รฉ executado quando essa rota รฉ bater.
Por exemplo, os dois trechos de cรณdigo a seguir alcanรงarรฃo a mesma coisa:
Exemplo #1: Definiรงรฃo e implementaรงรฃo de rota dentro de uma รบnica chamada de mรฉtodo (no arquivo de rotas web.php)
//inside routes/web.php
<?php
Route::get('/hello-world', function(Request $request) {
$name = $request->name;
return response()->make("<h1>Hello World! This is ".$name, 200);
});
Exemplo #2: A definiรงรฃo da rota estรก dentro de rotas/web.php, mas sua implementaรงรฃo reside dentro da classe /app/Http/Controllers/HelloWorldController
//inside routes/web.php
<?php
Route::get('/hello-world', 'HelloWorldController@index')->name('hello-world');
------------------------------------------------------------------------------------
//inside app/Http/Controllers/HelloWorldController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HelloWorldController extends Controller
{
public function index(Request $request)
{
$name = $request->name;
return response()->make("<h1>Hello World! This is ".$name, 200);
}
}
Embora o exemplo 2 do Laravel pareรงa muito mais trabalhoso (o que nรฃo รฉ - apenas um pouco mais de cรณdigo), observe os benefรญcios que ganhamos ao colocar nossa lรณgica de aรงรฃo para a rota โhello-worldโ fornecida dentro de um controlador. da definiรงรฃo da rota como uma funรงรฃo de retorno de chamada:
- Nossa lรณgica estรก claramente separada em sua prรณpria classe (separaรงรฃo de interesses)
- Nosso controlador estรก configurado para extensรฃo mais tarde se precisarmos adicionar recursos adicionais a eleโฆ Digamos que talvez quisรฉssemos adicionar um recurso โadeus mundoโโฆ Nesse caso, renomearรญamos o controlador para um โHelloControllerโ mais genรฉrico e depois definirรญamos dois mรฉtodos separados, Olรก() e ferrolhos de sobrepor podem ser usados para proteger uma porta de embutir pelo lado de fora. Alguns kits de corrente de seguranรงa tambรฉm permitem travamento externo com chave ou botรฃo giratรณrio. adeus(). Tambรฉm precisarรญamos definir duas rotas separadas que mapeassem o /olรก e ferrolhos de sobrepor podem ser usados para proteger uma porta de embutir pelo lado de fora. Alguns kits de corrente de seguranรงa tambรฉm permitem travamento externo com chave ou botรฃo giratรณrio. / adeus URIs para seu mรฉtodo apropriado no controlador. Isso รฉ desejรกvel em comparaรงรฃo com a engorda de um arquivo de rotas com a implementaรงรฃo de cada rota definida como funรงรตes de retorno de chamada.
- O Laravel tem a capacidade integrada de armazenar em cache todas as definiรงรตes de rota no aplicativo para acelerar o tempo necessรกrio para encontrar uma determinada rota (aumenta o desempenho do aplicativo); Contudo, vocรช sรณ poderรก tirar vantagem disso se todas as rotas definidas dentro do aplicativo estiverem configuradas usando mapeamentos especรญficos do controlador (veja o Exemplo nยบ 2 acima)
Vamos executar este comando que irรก gerar um novo controlador para nรณs.
// ...inside the project's root directory: php artisan make:controller UploadController
Essencialmente, o que este comando faz รฉ gerar um stub para um controlador chamado โUploadControllerโ dentro do diretรณrio principal do controlador em /app/Http/Controllers/UploadController.php. Sinta-se ร vontade para abrir esse arquivo e dar uma olhada. ร muito simples porque รฉ apenas uma versรฃo fragmentada do controlador, com o caminho correto do namespace e as classes necessรกrias das quais ele se estende.
Gerando a solicitaรงรฃo
Antes de prosseguirmos neste tutorial do PHP Laravel e fazer algumas alteraรงรตes no stub gerado pelo UploadController, acho que farรก mais sentido criar a classe de solicitaรงรฃo primeiro. Isso ocorre porque o mรฉtodo controlador que trata a solicitaรงรฃo deve digitar hint o objeto da solicitaรงรฃo em sua assinatura, permitindo validar automaticamente os dados do formulรกrio recebido (conforme especificado no mรฉtodo regras(). Mais sobre isso mais tardeโฆ) Por enquanto, vamos usar o comando artesรฃo novamente para gerar nosso stub de solicitaรงรฃo:
php artisan make:request UploadFileRequest
Este comando irรก gerar um arquivo chamado UploadFileRequest dentro de app/Http/Requests/UploadFileRequest. Abra o stub e dรช uma olhadaโฆ Vocรช vai achar muito simples, contendo apenas dois mรฉtodos, authorize() e regras.
Criando a lรณgica de validaรงรฃo
Vamos modificar o stub da solicitaรงรฃo para atender ร s necessidades da nossa aplicaรงรฃo. Modifique o arquivo para que fique assim:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UploadFileRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'fileName' => 'required|string',
'userFile' => 'required|file'
];
}
}
Nรฃo foram muitas mudanรงas, mas observe que o mรฉtodo authorize() agora retorna verdadeiro em vez de falso. Este mรฉtodo decide se permite ou nรฃo que a solicitaรงรฃo entre no aplicativo. Se for definido como falso, impede que a solicitaรงรฃo entre no sistema (o que normalmente seria um mรฉtodo no controlador). Este seria um local muito รบtil para colocar qualquer verificaรงรฃo de autorizaรงรฃo no usuรกrio ou qualquer outra lรณgica que possa decidir se a solicitaรงรฃo pode avanรงar para o controlador. Por enquanto, apenas retornamos true aqui para permitir que tudo e qualquer coisa use a solicitaรงรฃo.
O outro mรฉtodo, regras() รฉ onde toda a mรกgica entra em aรงรฃo no que diz respeito ร validaรงรฃo. A ideia รฉ simples: retornar um array contendo um conjunto de regras na forma de:
'formFieldName' => 'constraints this field has separated by pipe characters (|)'
Existem muitas restriรงรตes de validaรงรฃo diferentes que sรฃo suportadas pelo Laravel imediatamente. Para uma lista completa deles, verifique a documentaรงรฃo online aqui.. Para nosso aplicativo de upload, haverรก dois campos que serรฃo passados โโvia solicitaรงรฃo POST de um formulรกrio no front end. O parรขmetro fileName deve ser incluรญdo dentro do corpo do formulรกrio (ou seja, obrigatรณrio) e รฉ usado como o nome do arquivo sob o qual armazenaremos o arquivo no armazenamento (isso รฉ feito no controlador - falaremos disso um pouco mais tarde). Tambรฉm especificamos que o nome do arquivo deve ser uma string adicionando uma barra vertical (|) e a palavra 'string'. As restriรงรตes sรฃo sempre delimitadas por barras verticais, permitindo especificar quaisquer critรฉrios adicionais para um determinado campo em uma รบnica linha! Que poder!
O segundo parรขmetro, userFile , รฉ o arquivo real que o usuรกrio carrega de um formulรกrio em uma pรกgina da web. UserFile tambรฉm รฉ necessรกrio e devo ser um arquivo. Observaรงรฃo: Se esperรกssemos que o arquivo enviado fosse uma imagem, usarรญamos a restriรงรฃo de imagem, o que limitaria os tipos de arquivo aceitos a um dos tipos de imagem populares (jpeg, png, bmp, gif ou svg). Como queremos permitir que o usuรกrio faรงa upload de qualquer tipo de arquivo, seguiremos apenas a restriรงรฃo de validaรงรฃo de arquivo.
Isso รฉ tudo que existe no objeto de solicitaรงรฃo. Sua principal funรงรฃo รฉ simplesmente manter o conjunto aceitรกvel de critรฉrios (restriรงรตes) que os parรขmetros do corpo do formulรกrio devem satisfazer para prosseguir mais profundamente na aplicaรงรฃo. Outra coisa a observar รฉ que esses dois campos (userFile e filename) tambรฉm devem ser especificados dentro do cรณdigo HTML na forma de campos de entrada (com o nome do campo correspondente ao nome dentro do objeto de solicitaรงรฃo).
Vocรช pode estar se perguntando: claro que isso define as caracterรญsticas do que uma solicitaรงรฃo de formulรกrio deve conter, mas onde รฉ feita a verificaรงรฃo real dessas restriรงรตes? Entraremos nisso a seguir.
Modificando o controlador
Abra app/Http/Controllers/UploadController e faรงa as seguintes alteraรงรตes:
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use App\Http\Requests\UploadFileRequest; //our new request class
use Illuminate\Support\Facades\Storage;
class UploadController extends Controller
{
/**
* This is the method that will simply list all the files uploaded by name and provide a
* link to each one so they may be downloaded
*
* @param $request : A standard form request object
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws BindingResolutionException
*/
public function list(Request $request)
{
$uploads = Storage::allFiles('uploads');
return view('list', ['files' => $uploads]);
}
/**
* @param $file
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
* @throws BindingResolutionException
*/
public function download($file)
{
return response()->download(storage_path('app/'.$file));
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws BindingResolutionException
*/
public function upload()
{
return view('upload');
}
/**
* This method will handle the file uploads. Notice that the parameter's typehint
* is the exact request class we generated in the last step. There is a reason for this!
*
* @param $request : The special form request for our upload application
* @return array|\Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|null
* @throws BindingResolutionException
*/
public function store(UploadFileRequest $request)
{
//At this point, the parameters passed into the $request (from form) are
//valid--they satisfy each of the conditions inside the rules() method
$filename = $request->fileName; //parameters have already been validated
$file = $request->file('userFile'); //that we don't need any additional isset()
$extension = $file->getClientOriginalExtension(); //grab the file extension
$saveAs = $filename . "." . $extension; //filename to save file under
$file->storeAs('uploads', $saveAs, 'local'); //save the file to local folder
return response()->json(['success' => true]); //return a success message
}
}
Portanto, รฉ uma abordagem bastante simples para salvar os arquivos enviados em disco. Aqui estรก um detalhamento do mรฉtodo upload() acima:
- Digite a classe de solicitaรงรฃo no mรฉtodo do controlador que estรก executando a funcionalidade 'carne e batatas' para que possamos validar automaticamente os dados recebidos
- Pegue o arquivo do objeto de solicitaรงรฃo (agora validado) dentro do mรฉtodo do controlador (neste caso, nรณs o chamamos de upload(), mas tambรฉm poderia ter sido nomeado com um nome mais padronizado, como store()).
- Pegue o nome do arquivo da solicitaรงรฃo
- Gere o nome do arquivo final que serรก usado para salvar o arquivo. O mรฉtodo getClientOriginalExtension() simplesmente captura a extensรฃo original do arquivo carregado.
- Armazene o arquivo no sistema de arquivos local usando seu mรฉtodo storeAs(), passando o caminho nomeado dentro do diretรณrio /storage como o primeiro argumento e o nome do arquivo para salvรก-lo como o segundo.
- Retornar uma resposta JSON indicando que a solicitaรงรฃo foi bem-sucedida
O modelo de lรขmina
A รบltima peรงa importante deste quebra-cabeรงa รฉ o modelo blade, que conterรก todo HTML, CSS e javascript para nosso aplicativo simples. Aqui estรก o cรณdigo โ explicaremos mais tarde.
<body>
<h1>Upload a file</h1>
<form id="uploadForm" name="uploadForm" action="{{route('upload')}}" enctype="multipart/form-data">
@csrf
<label for="fileName">File Name:</label>
<input type="text" name="fileName" id="fileName" required /><br />
<label for="userFile">Select a File</label>
<input type="file" name="userFile" id="userFile" required />
<button type="submit" name="submit">Submit</button>
</form>
<h2 id="success" style="color:green;display:none">Successfully uploaded file</h2>
<h2 id="error" style="color:red;display:none">Error Submitting File</h2>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$('#uploadForm').on('submit', function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
url: url,
type: "POST",
data: new FormData(this),
processData: false,
contentType: false,
dataType: "JSON",
success: function(data) {
$("#fileName").val("");
$("#userFile").val("");
}
}).done(function() {
$('#success').css('display', 'block');
window.setTimeout(()=>($("#success").css('display', 'none')), 5000);
}).fail(function() {
$('#error').css('display', 'block');
window.setTimeout(()=>($("#error").css('display', 'none')), 5000);
});
});
</script>
</body>
</html>
Aqui estรก o que nosso / Envio pรกgina parece com:
Este รฉ um exemplo muito tรญpico de arquivo blade contendo um formulรกrio HTML e javascript/jQuery para adicionar funcionalidade assรญncrona (para que a pรกgina nรฃo seja atualizada). Existe um bรกsico tag sem nenhum atributo de mรฉtodo (que explicarei em apenas um segundo) e com um curioso atributo de aรงรฃo com o valor {{route('file.upload')}}. Na lรขmina, isso รฉ conhecido como Directiva. Uma diretiva รฉ apenas um nome sofisticado para funรงรฃo โ sรฃo funรงรตes especรญficas para modelos blade que executam diferentes operaรงรตes comuns ร construรงรฃo de pรกginas e aplicativos da web. Para uma melhor compreensรฃo de todas as coisas legais que o blade pode fazer, confira a documentaรงรฃo aqui.. No caso acima, estamos usando a diretiva route para gerar uma URL para o envio do nosso formulรกrio.
Lembre-se que definimos nossas rotas anteriormente na aplicaรงรฃo dentro do arquivo web.php, especificando um nome fรกcil de lembrar para cada uma delas. A diretiva {{route()}} aceita o nome de uma rota, procura-o na lista de rotas armazenadas em cache internamente e gera uma URL completa com base na definiรงรฃo dessa rota no arquivo web.php. Para este primeiro caso, estamos especificando que queremos que o formulรกrio envie os dados submetidos para a URL /process da nossa aplicaรงรฃo, que รฉ definida como um POST rota.
A prรณxima coisa estranha que vocรช deve ter notado รฉ a tag @csrf logo abaixo da tag do formulรกrio de abertura. No blade, essa tag gera um parรขmetro _token no formulรกrio, que รฉ verificado dentro do aplicativo antes que os dados do formulรกrio possam ser processados. Isso garante que os dados dentro do formulรกrio sejam de origem vรกlida e evita ataques de falsificaรงรฃo de solicitaรงรฃo entre sites. Para mais informaรงรตes sobre isso, consulte o docs.
Depois disso definimos nosso formulรกrio como normal, porรฉm observe que os nomes dos parรขmetros do nosso formulรกrio, userFile e fileName sรฃo os exatamente o mesmo conforme definido em nosso objeto de solicitaรงรฃo. Se esquecermos de incluir uma entrada para um determinado parรขmetro que foi definido no objeto de solicitaรงรฃo (ou digitรก-lo incorretamente), a solicitaรงรฃo falharรก e um erro serรก retornado, evitando que a solicitaรงรฃo do formulรกrio original atinja o mรฉtodo do controlador localizado em UploadController@ processo .
Experimente e envie alguns arquivos para o aplicativo usando este formulรกrio. Depois, navegue atรฉ o /Lista pรกgina para ver o conteรบdo da pasta de upload, com os arquivos que vocรช enviou listados em uma tabela:
The Bigger Picture
Vamos dar um passo atrรกs e ver o que fizemos neste tutorial do Laravel.
Este diagrama descreve o aplicativo como estรก no momento (excluindo detalhes de alto nรญvel):
Vocรช deve se lembrar que o objeto de solicitaรงรฃo que construรญmos no inรญcio deste tutorial do Laravel deve ter os mesmos parรขmetros definidos em seu mรฉtodo de regras que estรฃo no formulรกrio no modelo blade (se nรฃo, releia a seรงรฃo โCriando a Lรณgica de Validaรงรฃoโ) . O usuรกrio insere o formulรกrio em uma pรกgina da web que รฉ renderizada por meio de um mecanismo de modelo blade (รฉ claro que esse processo estรก no piloto automรกtico, entรฃo nรฃo precisamos nem pensar nisso) e envia o formulรกrio. O cรณdigo jQuery do modelo na parte inferior interrompe o envio padrรฃo (que redirecionaria automaticamente para uma pรกgina separada), cria uma solicitaรงรฃo ajax, carrega a solicitaรงรฃo com os dados do formulรกrio e carrega o arquivo, e envia tudo para a primeira camada do nosso aplicaรงรฃo: o pedido.
O objeto de solicitaรงรฃo รฉ preenchido associando os parรขmetros dentro do mรฉtodo regras() aos parรขmetros do formulรกrio enviado e, em seguida, valida os dados de acordo com cada regra especificada. Se todas as regras forem satisfeitas, a solicitaรงรฃo serรก repassada para qualquer mรฉtodo do controlador que corresponda aos valores definidos no arquivo de rota web.php. Nesse caso, รฉ o mรฉtodo process() do UploadController que faz o trabalho. Assim que atingimos o controlador, jรก sabemos que a solicitaรงรฃo passou na validaรงรฃo, entรฃo nรฃo precisamos testar novamente se o nome do arquivo fornecido รฉ, de fato, uma string ou se o parรขmetro userFile realmente contรฉm algum tipo de arquivoโฆ Podemos continuar como normal.
O mรฉtodo do controlador entรฃo pega os parรขmetros validados do objeto de solicitaรงรฃo, gera um nome de arquivo completo concatenando o parรขmetro fileName passado com a extensรฃo original do userFile, armazena o arquivo dentro de um diretรณrio em nosso aplicativo e retorna um arquivo simples codificado em JSON resposta verificando se a solicitaรงรฃo foi bem-sucedida. A resposta รฉ recebida pela lรณgica jQuery, que realiza mais algumas tarefas relacionadas ร UI, como exibir a mensagem de sucesso (ou erro) por 5 segundos e depois ocultรก-la, bem como limpar as entradas anteriores do formulรกrioโฆ isso รฉ para que o usuรกrio saiba ter certeza de que a solicitaรงรฃo foi bem-sucedida e poderรก fazer upload de outro arquivo, se desejar.
Alรฉm disso, observe no diagrama acima exatamente onde a linha รฉ traรงada entre o cliente e o servidor. Este conceito รฉ absolutamente crรญtico para vocรช entender e irรก ajudรก-lo a resolver problemas e questรตes que vocรช possa ter no futuro ao lidar, por exemplo, com mรบltiplas solicitaรงรตes assรญncronas que podem ocorrer a qualquer momento. A separaรงรฃo estรก bem no limite do objeto de solicitaรงรฃo. O prรณprio objeto de solicitaรงรฃo pode ser considerado o โgatewayโ para o resto da aplicaรงรฃoโฆ Ele faz a validaรงรฃo inicial e o registro dos valores do formulรกrio transmitidos pelo navegador da web. Se forem considerados vรกlidos, o processo continua para o controlador. Tudo antes disso estรก no front-end (o โclienteโ significa literalmente โno computador do usuรกrioโ). A resposta รฉ retornada do aplicativo de volta para o lado do cliente, onde nosso cรณdigo jQuery escuta pacientemente sua chegada e executa algumas tarefas simples de UI assim que a recebe.
Cobrimos quase 90 perguntas importantes e frequentes Perguntas da entrevista relacionadas ao Laravel e PHP para calouros e tambรฉm para candidatos experientes conseguirem o emprego certo.







