Tutoriel Laravel pour les débutants

Qu'est-ce que Laravel?

Laravel est un framework Web MVC open source pour PHP. Laravel est un framework robuste qui permet de développer facilement des applications Web PHP avec des fonctionnalités telles qu'un système de packaging modulaire avec un gestionnaire de dépendances dédié, un accès aux bases de données relationnelles et d'autres utilitaires pour le déploiement et la maintenance des applications.

Laravel a été créé par Taylor Otwell. Depuis sa sortie initiale en juin 2011 (version 1), il est devenu de plus en plus populaire dans le secteur des frameworks PHP de l'industrie du développement Web. Une grande partie de cette popularité peut être attribuée aux nombreuses fonctionnalités destinées aux développeurs et fournies en stock.

Pourquoi Laravel ?

Vers 2000, la plupart Codes PHP était procédural et pouvait être trouvé sous la forme de « scripts » qui auraient un fouillis de code spaghetti. Même les pages les plus simples n'avaient pas séparation des préoccupations, et il était donc assez facile pour une application de se transformer rapidement en un cauchemar de maintenance. Le monde avait besoin de quelque chose de mieux… Entrez dans la version 5 de PHP et dans une variété de frameworks PHP pour tenter d'apporter une résolution indispensable et de meilleures solutions à divers problèmes d'applications Web.

Depuis lors, nous avons vu de nombreux frameworks publiés qui ouvriraient la voie aux frameworks populaires existants et utilisés aujourd'hui. Aujourd’hui, les trois premiers seraient (à notre avis) Zend Framework, Symfony et bien sûr Laravel. Bien que chacun de ces cadres soit fondé sur des principes similaires et vise à résoudre (essentiellement) les mêmes problèmes communs, leurs principales différences résident dans leur mise en œuvre. Ils ont chacun leurs propres particularités quant à la manière de résoudre les problèmes. Lorsque vous regardez le code produit par chacun d’eux, vous verrez qu’il y a une ligne assez solide qui les sépare les uns des autres. À notre humble avis, le framework Laravel est le meilleur.

En savoir plus sur Différence entre Laravel et CodeIgniter

Comment télécharger et installer Laravel avec Composer

REMARQUE Il est supposé que vous disposez déjà d’une copie de PHP installée sur votre système local. Sinon, vous pouvez lire comment l'installer ici

Composer est à la fois un gestionnaire de packages et de dépendances. Pour l'installer, ouvrez un terminal et cd dans un nouveau répertoire. Exécutez cette commande :

curl -Ss getcomposer.org/installer | php

Les résultats de cette commande ressembleront à ceci :

Téléchargez et installez Laravel avec Composer

Notes Pour des instructions plus détaillées sur la configuration de Laravel, reportez-vous à la documentation de Laravel. ici.

Vous le verrez télécharger et compiler le script composer.phar, que nous utilisons pour installer Laravel. Bien qu'il existe de nombreuses façons de configurer une nouvelle application Laravel, nous le ferons via le script Laravel composer. Pour installer ce script, exécutez :

composer global require laravel/installer

Ce qui ressemblera à ceci :

Téléchargez et installez Laravel avec Composer

Cela téléchargera et installera tous les fichiers du framework eux-mêmes ainsi que toutes les dépendances nécessaires. Les packages seront enregistrés dans le répertoire du fournisseur. Une fois téléchargé et installé, c'est aussi simple que d'exécuter la commande suivante :

laravel new uploadApp

Vous verrez quelque chose comme le résultat suivant :

Téléchargez et installez Laravel avec Composer

Composer installe tous les packages dont Laravel a besoin pour fonctionner. Cela peut prendre quelques minutes, alors soyez patient. Une fois l’opération terminée, exécutez une commande ls -al pour jeter un œil à ce qui a été installé.

Voici une brève description des répertoires dans une application Laravel courante :

  • application/ : Il s'agit du dossier source où réside notre code d'application. Tous les contrôleurs, stratégies et modèles se trouvent dans ce dossier
  • amorcer/ : Contient le script de démarrage de l'application et quelques fichiers de mappage de classes
  • configuration/ : Contient les fichiers de configuration de l'application. Celles-ci ne sont généralement pas modifiées directement mais s'appuient plutôt sur les valeurs définies dans le fichier .env (environnement) à la racine de l'application.
  • base de données/ : Héberge les fichiers de base de données, y compris les migrations, les graines et les usines de tests
  • publique/ : Dossier accessible au public contenant les actifs compilés et bien sûr un fichier index.php
  • ressources/ : Contient des ressources frontales telles que des fichiers javascript, des fichiers de langue, des fichiers CSS/SASS et tous les modèles utilisés dans l'application (appelés modèles de lame)
  • itinéraires/ : Tous les itinéraires de l'application se trouvent ici. Il existe différentes « portées » de routes, mais celle sur laquelle nous nous concentrerons est le fichier web.php.
  • stockage/ : Tous les fichiers de cache temporaires utilisés par l'application, les fichiers de session, les scripts de vue compilés et les fichiers journaux
  • essais/ : Contient des fichiers de test pour l'application tels que des tests unitaires et des tests fonctionnels.
  • fournisseur/ : Tous les packages de dépendances installés avec composer

Maintenant, créons le reste de l'application et exécutons-la avec une commande artisanale spéciale (pour nous épargner les tracas liés à l'installation et à la configuration d'un serveur Web comme Apache ou nginx). Le fichier .env contient toutes les valeurs de configuration que les fichiers du répertoire /config utilisent pour configurer l'application. À l’intérieur, vous remarquerez la valeur de configuration de divers paramètres utilisés par les composants internes de l’application.

Conception d’applications : un aperçu rapide de nos exigences

Dans ce didacticiel Laravel en ligne, nous allons créer une application très simple qui ne fera que deux choses :

  1. gérer les téléchargements de fichiers à partir d'un formulaire Web
  2. afficher les fichiers précédemment téléchargés sur une page différente.

Pour ce projet, notre application sera en écriture seule, ce qui signifie que l'utilisateur pourra uniquement écrire des fichiers et afficher la liste des fichiers qu'il a téléchargés. Cette application est extrêmement basique mais devrait servir de bonne pratique pour commencer à développer vos compétences et connaissances Laravel. Notez que par souci de concision, j'ai exclu toute modélisation, migration et authentification de base de données mais, dans une application réelle, ce sont des éléments supplémentaires que vous voudrez prendre en compte.

Voici une liste des composants dont nous aurons besoin pour que l'application fonctionne comme prévu :

  • A route qui permettra au monde extérieur (Internet) d'utiliser l'application et de spécifier le point de terminaison qui indiquera où se trouve la logique de sauvegarde du fichier téléchargé
  • A contrôleur qui gère le flux de requête vers réponse
  • A modèle qui sera utilisé pour afficher une liste des fichiers précédemment téléchargés et le formulaire de téléchargement lui-même
  • A nécessaire que le responsable du traitement utilisera pour valider les données transmises à partir du formulaire Web

Qu’est-ce qu’un itinéraire ?

Une route dans Laravel est essentiellement un point de terminaison spécifié par un URI qui agit comme un « pointeur » vers une fonctionnalité offerte par l’application. Le plus souvent, une route pointe simplement vers une méthode sur un contrôleur et dicte également quelles méthodes HTTP peuvent accéder à cet URI. Un itinéraire ne signifie pas non plus toujours une méthode de contrôleur ; il pourrait également simplement transmettre l'exécution de l'application à une fermeture définie ou à une fonction anonyme.

Pourquoi utiliser Route ?

Les routes sont stockées dans des fichiers sous le dossier /routes dans le répertoire racine du projet. Par défaut, il existe quelques fichiers différents correspondant aux différents « côtés » de l'application (« côtés » vient de la méthodologie de l'architecture hexagonale). Ils comprennent:

  • web.php Les itinéraires publics basés sur un « navigateur ». Ce sont les plus courants et c’est ce qui est touché par le navigateur Web. Ils fonctionnent via le groupe de middleware Web et contiennent également des fonctionnalités pour protection csrf (qui aide à se défendre contre les attaques malveillantes et les piratages basés sur des formulaires) et contiennent généralement un certain degré « d'état » (j'entends par là qu'ils utilisent des sessions)
  • api.php Routes qui correspondent à un groupe d'API et dont le middleware API est donc activé par défaut. Ces routes sont sans état et n'ont pas de sessions ni de mémoire de requêtes croisées (une requête ne partage pas de données ou de mémoire avec une autre requête – chacune est auto-encapsulée).
  • console.php Ces itinéraires correspondent aux commandes artisanales personnalisées que vous avez créées pour votre application
  • channels.php Enregistre les itinéraires pour la diffusion d'événements

Le fichier clé à prendre en compte à ce stade est celui spécifique au navigateur, web.php . Il existe déjà une route définie par défaut, qui est celle que vous cliquez directement lors de la navigation vers la racine Web de votre application (la racine Web se trouve dans le répertoire public). Nous aurons besoin de trois itinéraires différents pour que notre application de téléchargement fonctionne :

  • /upload Ce sera l'URI de la page principale affichant notre formulaire Web pour télécharger des fichiers.
  • /process Ce sera l'endroit où le formulaire situé à l'URI /upload publie les données soumises par le formulaire (l'« action » du formulaire).
  • /list Ceci listera tous les fichiers téléchargés sur le site

noter Le point de terminaison /list n'est peut-être pas nécessaire si nous souhaitons mettre toute la logique d'affichage du formulaire de téléchargement et de la liste des fichiers sur une seule page, cependant, nous les avons gardés séparés pour l'instant pour ajouter un peu plus de matière au sujet traité. .

//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');

Dans ce tutoriel du framework Laravel, pour chaque route souhaitée, nous la listerons explicitement dans le fichier de routes web.php en utilisant l'une des méthodes de requête spécifiques à HTTP disponibles (get(), post(), put() , delete(), patch() ou options() ). Pour une ventilation de chacun d’eux, consultez ceci. dehors. Ces méthodes précisent quels verbes HTTP sont autorisés à accéder à cette route donnée. Si vous avez besoin d'une route pour pouvoir accepter plus d'un verbe HTTP (ce qui peut être le cas si vous utilisez une seule page pour afficher à la fois les données initiales et les données du formulaire post-soumis), vous pouvez utiliser Route::any( ) méthode.

Le deuxième argument des méthodes Route::get() et Route::post() (et de toutes les autres méthodes liées au verbe HTTP sur la façade Route) est le nom d'un contrôleur spécifique et d'une méthode hébergée à l'intérieur de celui-ci. contrôleur qui est exécuté lorsqu'il atteint le point de terminaison de la route avec la requête HTTP autorisée (GET, POST, PATCH, etc.). Nous utilisons UploadController pour les trois routes et les avons spécifiés de la manière suivante :

Qu'est-ce qu'un itinéraire

La dernière méthode que nous appelons sur chaque route est sa fonction name(), qui accepte une seule chaîne comme argument et est utilisée pour plus ou moins « étiqueter » une route particulière avec un nom facile à retenir (dans notre cas, téléchargement, traitement et liste). Je me rends compte que cela ne semble pas une fonctionnalité très intéressante de donner à chaque route son propre nom lorsque l'URL porte exactement le même nom, mais cela s'avère vraiment utile lorsque vous avez une route spécifique comme /users/profile/dashboard/config, ce qui serait plus facile à retenir en tant que profile-admin ou user-config.

Une note sur les façades :

  • Les façades fournissent une interface « statique » aux classes disponibles dans le conteneur de services de l'application.
  • Ils fournissent une syntaxe concise et mémorable qui vous permet d'utiliser les fonctionnalités de Laravel sans vous souvenir des noms de classe longs qui doivent être injectés ou configurés manuellement.

Dans les définitions de route ci-dessus dans ce didacticiel du framework Laravel, nous utilisons la façade Route au lieu d'instancier manuellement un nouvel objet Illuminate/Routing/Router et d'appeler les méthodes correspondantes sur cet objet. C'est juste un raccourci qui évite de taper. Les façades sont largement utilisées dans tout le framework Laravel – vous pouvez et devez vous familiariser davantage avec elles. Les documents pour les façades peuvent être trouvés ici.

Qu'est-ce qu'un contrôleur ?

Un contrôleur est le « C » de l’architecture « MVC » (Model-View-Controller), sur laquelle est basé Laravel. Le travail d'un contrôleur peut se résumer à cette simple définition : Il reçoit la demande du client et renvoie une réponse au client. Il s’agit de la définition simple et constitue également la configuration minimale requise pour tout contrôleur donné. Ce qu'il fait entre ces deux choses est généralement considéré comme « l'action » du contrôleur (ou la « mise en œuvre de la route »). Il agit comme le deuxième point d'entrée de l'application (le premier étant la requête) pour le client, qui envoie la charge utile de la requête (que nous aborderons ensuite) à l'application, en attendant un certain type de réponse (sous la forme d'un page de réussite, redirection, page d'erreur ou tout autre type de réponse HTTP).

Un contrôleur fait (essentiellement) la même chose qu'une définition de route avec une fonction anonyme définie comme « action » lorsque cette route est atteinte. La différence est qu'un contrôleur résiste bien à la séparation des préoccupations tandis qu'une route est définie en ligne avec la définition réelle de l'URL, ce qui signifie essentiellement que nous associons l'URI attribué à la route avec l'implémentation de la route, ou le code qui s'exécute lorsque cette route est frapper.

Par exemple, les deux morceaux de code suivants permettront d’obtenir le même résultat :

Exemple n°1 : définition et implémentation de la route dans un seul appel de méthode (dans le fichier routes 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);
});

Exemple n°2 : la définition de la route se trouve dans routes/web.php, mais son implémentation réside dans la 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);
   }
}

Bien que l'exemple n°2 de Laravel semble demander beaucoup plus de travail (ce qui n'est pas le cas, juste un peu plus de code, c'est tout), regardez les avantages que nous obtenons en plaçant notre logique d'action pour la route « hello-world » donnée à l'intérieur d'un contrôleur. de avec la définition de la route comme fonction de rappel :

  1. Notre logique est proprement séparée dans sa propre classe (séparation des préoccupations)
  2. Notre contrôleur est configuré pour une extension ultérieure si nous devions lui ajouter des fonctionnalités supplémentaires… Disons que nous voulions peut-être ajouter une fonctionnalité « au revoir au monde »… Dans ce cas, nous renommerions le contrôleur en un « HelloController » plus générique, puis définirions deux méthodes distinctes, Bonjour() et le au revoir(). Nous aurions également besoin de définir deux itinéraires distincts qui cartographient le /salut et le / Au revoir URI à leur méthode appropriée sur le contrôleur. Ceci est souhaitable par rapport à l'enrichissement d'un fichier de routes avec l'implémentation de chaque route définie comme fonctions de rappel.
  3. Laravel a la capacité intégrée de mettre en cache toutes les définitions d'itinéraire dans l'application afin d'accélérer le temps nécessaire pour trouver un itinéraire donné (augmente les performances de l'application) ; Cependant, vous ne pourrez en profiter que si toutes vos routes définies dans l'application sont configurées à l'aide de mappages spécifiques au contrôleur (voir l'exemple n°2 ci-dessus)

Exécutons cette commande qui générera un nouveau contrôleur pour nous.

// ...inside the project's root directory:
php artisan make:controller UploadController   

Essentiellement, cette commande génère un stub pour un contrôleur nommé « UploadController » dans le répertoire du contrôleur principal à l'adresse /app/Http/Controllers/UploadController.php. N'hésitez pas à ouvrir ce fichier et à y jeter un œil. C'est très simple car il ne s'agit que d'une version tronquée du contrôleur, avec le chemin d'accès correct à l'espace de noms et les classes requises à partir desquelles il s'étend.

Générer la demande

Avant d'aller de l'avant dans ce didacticiel PHP Laravel et d'apporter quelques modifications au stub généré par UploadController, je pense qu'il sera plus logique de créer d'abord la classe de requête. En effet, la méthode du contrôleur qui gère la requête doit saisir l'objet de la requête dans sa signature, ce qui lui permet de valider automatiquement les données du formulaire entrant (comme spécifié dans la méthode Rules(). Nous en reparlerons plus tard…) Pour l'instant, utilisons la commande artisan à nouveau pour générer notre talon de demande :

php artisan make:request UploadFileRequest

Cette commande générera un fichier appelé UploadFileRequest dans app/Http/Requests/UploadFileRequest. Ouvrez le stub et jetez-y un œil… Vous le trouverez très simple, ne contenant que deux méthodes, authorize() et les règles.

Création de la logique de validation

Modifions le stub de la demande pour répondre aux besoins de notre application. Modifiez le fichier pour qu'il ressemble à ceci :

<?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'
       ];
   }
}

Pas beaucoup de changements, mais notez que la méthode authorize() renvoie désormais true au lieu de false. Cette méthode décide d'autoriser ou non l'entrée de la requête dans l'application. S'il est défini sur false, cela empêche la requête d'entrer dans le système (ce qui serait normalement une méthode sur le contrôleur). Ce serait un endroit très pratique pour effectuer des contrôles d'autorisation sur l'utilisateur ou toute autre logique pouvant décider si la demande peut être transmise au contrôleur. Pour l'instant, nous retournons simplement true ici pour permettre à tout et à tout d'utiliser la requête.

L’autre méthode, Rules(), est celle où toute la magie entre en jeu en matière de validation. L'idée est simple : renvoyer un tableau contenant un ensemble de règles sous la forme de :

'formFieldName' => 'constraints this field has separated by pipe characters (|)'

Il existe de nombreuses contraintes de validation différentes qui sont prises en charge par Laravel dès la sortie de la boîte. Pour une liste complète d'entre eux, consultez la documentation en ligne ici. Pour notre application de téléchargement, deux champs seront transmis via une requête POST à ​​partir d'un formulaire sur le front-end. Le paramètre fileName doit être inclus dans le corps du formulaire (c'est-à-dire obligatoire) et est utilisé comme nom de fichier sous lequel nous stockerons le fichier dans le stockage (cela se fait dans le contrôleur – nous y reviendrons un peu plus tard). Nous spécifions également que le nom du fichier doit être une chaîne en ajoutant un caractère barre verticale (|) et le mot « chaîne ». Les contraintes sont toujours délimitées par des barres verticales, vous permettant de spécifier d'éventuels critères supplémentaires pour le champ donné sur une seule ligne ! Quelle puissance !

Le deuxième paramètre, userFile , est le fichier réel que l'utilisateur télécharge à partir d'un formulaire sur une page Web. UserFile est également requis et must être un fichier. Remarque : Si nous nous attendions à ce que le fichier téléchargé soit une image, nous utiliserions plutôt la contrainte d'image, ce qui limiterait les types de fichiers acceptés comme étant l'un des types d'images populaires (jpeg, png, bmp, gif ou svg). Puisque nous voulons permettre à l’utilisateur de télécharger n’importe quel type de fichier, nous nous en tiendrons simplement à la contrainte de validation de fichier.

C’est à peu près tout ce qu’il y a à dire sur l’objet de requête. Son travail principal consiste simplement à contenir l'ensemble acceptable de critères (contraintes) auxquels les paramètres du corps du formulaire doivent satisfaire afin d'approfondir l'application. Une autre chose à noter est que ces deux champs (userFile et filename) doivent également être spécifiés à l'intérieur du code HTML sous forme de champs de saisie (avec le nom du champ correspondant au nom à l'intérieur de l'objet de requête).

Vous vous demandez peut-être : bien sûr, cela définit les caractéristiques de ce qu'une demande de formulaire doit contenir, mais où est effectuée la vérification réelle de ces contraintes ? Nous y reviendrons ensuite.

Modification du contrôleur

Ouvrez l'application/Http/Controllers/UploadController et apportez-y les modifications suivantes :

<?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
   }
}

Il s'agit donc d'une approche assez simple pour enregistrer les fichiers téléchargés sur le disque. Voici un aperçu de la méthode upload() ci-dessus :

  • Tapez un indice sur la classe de requête dans la méthode du contrôleur qui exécute la fonctionnalité « viande et pommes de terre » afin que nous puissions valider automatiquement les données entrantes.
  • Extrayez le fichier de l'objet de requête (maintenant validé) à l'intérieur de la méthode du contrôleur (dans ce cas, nous l'avons nommé upload() mais il aurait également pu être nommé sous un nom plus standardisé comme store()).
  • Extrayez le nom de fichier de la requête
  • Générez le nom de fichier final qui sera utilisé pour enregistrer le fichier sous. La méthode getClientOriginalExtension() récupère simplement l'extension d'origine du fichier téléchargé.
  • Stockez le fichier sur le système de fichiers local à l'aide de sa méthode storeAs(), en passant le chemin nommé dans le répertoire /storage comme premier argument et le nom de fichier sous lequel l'enregistrer comme second.
  • Renvoie une réponse JSON indiquant que la demande a réussi

Le modèle de lame

La dernière pièce majeure de ce puzzle est le modèle de lame, qui contiendra tous les HTML, CSS et javascript pour notre application simple. Voici le code – Nous l’expliquerons plus tard.

<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>

Voici ce que notre /télécharger la page ressemble à :

Le modèle de lame

Il s'agit d'un exemple très typique de fichier lame contenant un formulaire HTML et javascript/jQuery pour ajouter des fonctionnalités asynchrones (afin que la page ne soit pas actualisée). Il y a une base balise sans attribut de méthode (que je vais expliquer dans une seconde) et avec un curieux attribut d'action avec la valeur {{route('file.upload')}}. En lame, c'est ce qu'on appelle un Directive. Une directive n'est qu'un nom sophistiqué pour une fonction : ce sont des fonctions spécifiques aux modèles de lame qui effectuent différentes opérations communes à la construction de pages Web et d'applications Web. Pour une meilleure compréhension de toutes les conneries cool que Blade peut faire, consultez la documentation ici. Dans le cas ci-dessus, nous utilisons la directive route pour générer une URL pour la soumission de notre formulaire.

N'oubliez pas que nous avons défini nos routes plus tôt dans l'application dans le fichier web.php, en spécifiant un nom facile à retenir pour chacune d'elles. La directive {{route()}} accepte le nom d'une route, le recherche dans la liste des routes mises en cache en interne et génère une URL complète basée sur la définition de cette route dans le fichier web.php. Pour ce premier cas, nous précisons que nous souhaitons que le formulaire envoie ses données soumises à l'URL /process de notre application, qui est définie comme un POSTEZ trajet.

La prochaine chose étrange que vous avez peut-être remarquée est la balise @csrf juste en dessous de la balise d'ouverture du formulaire. Dans Blade, cette balise génère un paramètre _token sur le formulaire, qui est vérifié dans l'application avant que les données du formulaire puissent être traitées. Cela garantit que les données contenues dans le formulaire sont d'une origine valide et empêche les attaques de falsification de requêtes intersites. Pour plus d'informations à ce sujet, consultez le docs.

Après cela, nous définissons notre formulaire comme d'habitude, cependant, notez que les noms de nos paramètres de formulaire, userFile et fileName sont les noms de nos paramètres de formulaire, userFile et fileName. exactement la même tel que défini dans notre objet de requête. Si nous oubliions d'inclure une entrée pour un paramètre donné qui a été défini dans l'objet de requête (ou si nous l'avions mal orthographié), la requête échouerait et une erreur serait renvoyée, empêchant la requête de formulaire d'origine d'atteindre la méthode du contrôleur située dans UploadController@. processus .

Allez-y, essayez-le et soumettez quelques fichiers à l’application en utilisant ce formulaire. Ensuite, accédez au /liste pour voir le contenu du dossier de téléchargement, avec les fichiers que vous avez téléchargés répertoriés dans un tableau :

Le modèle de lame

The Bigger Picture

Prenons du recul et regardons ce que nous avons fait dans ce tutoriel Laravel.

Ce diagramme représente l'application telle qu'elle se présente actuellement (détails de haut niveau exclus) :

Diagramme du didacticiel Laravel

Vous devez vous rappeler que l'objet de requête que nous avons construit au début de ce didacticiel Laravel doit avoir les mêmes paramètres définis dans sa méthode de règles que sur le formulaire du modèle de lame (sinon, relisez la section « Création de la logique de validation ») . L'utilisateur saisit le formulaire dans une page Web rendue via un moteur de modèle de lame (ce processus est bien sûr en pilote automatique, nous n'avons donc même pas besoin d'y penser) et soumet le formulaire. Le code jQuery du modèle en bas arrête la soumission par défaut (qui redirigerait automatiquement vers une page séparée), crée une requête ajax, charge la requête avec les données du formulaire et télécharge le fichier, et envoie le tout dans la première couche de notre application : la demande.

L'objet de requête est rempli en associant les paramètres de la méthode Rules() aux paramètres du formulaire soumis, puis valide les données selon chaque règle spécifiée. Si toutes les règles sont satisfaites, la requête est transmise à la méthode du contrôleur correspondant aux valeurs définies dans le fichier de route web.php. Dans ce cas, c'est la méthode process() du UploadController qui fait le travail. Une fois que nous avons touché le contrôleur, nous savons déjà que la requête a réussi la validation, nous n'avons donc pas besoin de tester à nouveau si le nom de fichier donné est, en fait, une chaîne ou si le paramètre userFile contient réellement un type de fichier… Nous pouvons continuer ainsi normale.

La méthode du contrôleur récupère ensuite les paramètres validés de l'objet de requête, génère un nom de fichier complet en concaténant le paramètre fileName transmis avec l'extension d'origine de userFile, stocke le fichier dans un répertoire de notre application, puis renvoie un simple code JSON. réponse vérifiant que la demande a abouti. La réponse est reçue par la logique jQuery, qui effectue quelques tâches supplémentaires liées à l'interface utilisateur, telles que l'affichage du message de réussite (ou d'erreur) pendant 5 secondes, puis son masquage ainsi que l'effacement des entrées de formulaire précédentes… afin que l'utilisateur sache avec certitude que la demande a abouti et peut télécharger un autre fichier, s'il le souhaite.

Notez également dans le diagramme ci-dessus où la ligne est tracée entre le client et le serveur. Ce concept est absolument essentiel à comprendre et vous aidera à résoudre les problèmes que vous pourriez rencontrer à l'avenir lorsque vous jonglerez, par exemple, avec plusieurs requêtes asynchrones pouvant survenir à un moment donné. La séparation se situe juste à la limite de l'objet de la requête. L'objet de requête lui-même peut être considéré comme la « passerelle » vers le reste de l'application… Il effectue la validation initiale et l'enregistrement des valeurs du formulaire transmises par le navigateur Web. S'ils sont jugés valables, le traitement se poursuit. Tout ce qui précède se trouve sur le front-end (le « client » signifie littéralement « sur l'ordinateur de l'utilisateur »). La réponse est renvoyée de l'application vers le côté client, où notre code jQuery écoute patiemment son arrivée et effectue quelques tâches simples d'interface utilisateur une fois qu'il la reçoit.

Nous avons couvert près de 90+ questions fréquemment posées importantes Questions d'entretien liées à Laravel et PHP pour les débutants comme pour les candidats expérimentés pour obtenir le bon emploi.