Blade Pattern

The last important piece of this puzzle is the blade template, which will contain all the HTML, CSS, and javascript for our simple application. Here’s the code – I’ll explain later.

   <h1> Upload a file </h1>
   <form id = "uploadForm" name = "uploadForm" action = "{{route ('upload')}}" enctype = "multipart / form-data">
       <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>
   <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 = "//"> </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);

This is what our download page looks like :

This is a very typical example of a blade file containing an HTML form and javascript / jQuery to add asynchronous functionality (so the page doesn’t refresh). There is a basic <form> tag with no method attribute (which I’ll explain in a second) and a curious action attribute with the value {{route (‘file.upload’)}}. In the blade, this is what is known as a directive. The directive is just a fancy name for a function – these are functions specific to blade templates that perform various operations that are common to building web pages and web applications. For a better understanding of all the cool shit a blade can do . In the above case, we are using the route directive to generate the URL for submitting the form.

Remember that we defined our routes earlier in the application inside the web.php file, providing an easy-to-remember name for each one. The {{route ()}} directive takes the name of a route, looks for it in the list of internal cached routes and generates a full URL based on the definition of that route in the web.php file. In this first case, we are specifying that we want the form to submit its submitted data to our application’s / process URL, which is defined as a POST route.

The next weird thing you might have noticed is the @csrf tag just below the opening form tag. In the blade, this tag generates a _token parameter on the form, which is validated internally by the application before the form data is allowed to be processed. This ensures that the data inside the form is of valid origin and prevents cross-site-request-spoofing attacks.

After that we define our form as normal, however, note that the names of our form parameters, userFile and fileName, are exactly the same as defined inside our request object. If we forgot to include the input for a given parameter that was defined in the request object (or wrote it incorrectly), the request would fail and return an error preventing the original form request from reaching the controller method located at UploadController @ process.

Try it and submit some files to your application using this form. After that go to the / list page to see the contents of the download folder, and the files you downloaded are listed in the table:

Big picture

Let’s take a step back and see what we’ve done.

This diagram depicts the application as it is now (high-level details excluded):

You must remember that the request object we created at the beginning of this lesson must have the same parameters defined in its rules method as in the form in the blade template (unless you reread the section on Creating validation logic). The user enters a form on a web page that is rendered using the blades templating engine (this process is of course done on autopilot so we don’t even need to think about it) and submits the form. The jQuery template code at the bottom stops the default submission (which automatically redirects to a separate page), creates an ajax request, loads the request with the form data and uploads the file and sends it all to the first layer of our Application: request.

The request object is populated by binding parameters within the rules () method to the submitted form parameters, and then validating the data against each specified rule. If all the rules are satisfied, the request is passed to any controller method that matches the values ​​defined in the web.php route file. In this case, it’s the process () method of UploadController that does the work. After we get into the controller, we already know that the request passed validation, so we don’t need to re-check if the given filename is actually a string or a userFile parameter, actually contains some type of file … We can continue as usually.

The controller method then extracts the validated parameters from the request object, generates the fully qualified filename by concatenating the passed fileName parameter with the original userFile extension, stores the file in a directory in our application, then returns a simple JSON-encoded response confirming that the request was successful. The answer comes from jQuery logic, which performs a few more UI related tasks such as displaying a success (or error) message for 5 seconds, then hiding it, and clearing previous form entries … this is so User knows for sure that the request is was successful, and can download another file if desired.

Also notice the diagram above where the line goes between client and server. This concept is absolutely essential to understand and will help you solve problems and problems that may arise in the future when juggling, such as multiple asynchronous requests that may arise at any given time. The split happens right at the border of the request object. The request object itself can be thought of as a “gateway” to the rest of the application … It does the initial validation and registration of form values ​​submitted from the web browser. If they are considered valid, then this continues to the controller. Everything before that is at the forefront (“client” literally means “on the user’s computer”). The response is returned from the application back to the client side,

What is a controller in laravel?

The controller is the “C” in the “MVC” (Model-View-Controller) architecture that Laravel is based on. A controller can be reduced to this simple definition: it receives a request from the client and returns a response to the client. This is a simple definition as well as the minimum requirements for any given controller. What it does in between the two is usually seen as an “action” by the controller (or “route implementation”). It acts as a second entry point into the application (the first is the request) for the client, which sends the request payload (which we will receive next) to the application, waiting for some type of response (in the form of a success page, redirect, error page, or any other kind of HTTP response) ).

The controller does (basically) the same as defining a route, with an anonymous function set to “action” when that route is reached. The difference is that the controller does a good job of separating concerns, while the route is determined according to the actual URL definition, which basically means we associate the assigned route URI with the route implementation, or the code that gets executed when that route is hit …

For example, the following two code snippets will achieve the same:

Example # 1: defining and implementing a route within one method call (in the web.php routes file)

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

Example # 2. The route definition is in route / web.php, but its implementation is in the class / 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);

While example # 2 looks much more time consuming (and it isn’t – just a little more code – that’s it), let’s take a look at the benefits we get by instead placing our action logic for a given “hello-world” route inside a controller from the route definition into as a callback function:

  1. Our logic is clearly divided into a class of its own (separation of interests)
  2. Our controller will be configured to extend later if we need to add more functionality to it … Let’s say maybe we want to add a goodbye function … In this case, we’ll rename the controller to the more generic “HelloController” then define two separate methods, hello () and goodbye () . We would also need to define two separate routes that map the / hello and / goodbye URIs to their respective methods on the controller. This is desirable compared to populating a routes file with the implementation of each route defined as a callback function.
  3. Laravel has a built-in ability to cache all route definitions in an application to speed up the time it takes to find a given route (increases application performance); however, you will only be able to take advantage of this if all the routes you define within the application are configured using controller-specific bindings (see example # 2 above)

Let’s run this command, which will generate a new controller for us.

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

Basically, this command generates a stub for a controller named “UploadController” inside the main controller directory at /app/Http/Controllers/UploadController.php. Feel free to open this file and see. This is very easy because it is only a mocked version of the controller with the correct namespace path and the required classes from which it extends.

What is a route in laravel?

A route in Laravel is essentially an endpoint specified by a URI that acts as a “pointer” to some piece of functionality offered by the application. More often than not, the route simply points to a method on the controller and also indicates which HTTP methods can use that URI. Route also does not always mean a controller method; it can simply pass the execution of the application to a specific Closure function or anonymous function.

Why use a route?

Routes are stored in files in the / routes folder inside the project root. By default, there are several different files corresponding to different “sides” of the application (“sides” come from the hexagonal architecture methodology). These include:

  • web.php Routes based on public browsers. These are the most common and this is what gets into the web browser. They go through the web middleware group and also contain csrf protections (which help defend against malicious attacks and form-based hacks) and usually contain some degree of “state” (by which I mean they use sessions)
  • api.php Routes that match the API group and therefore have API middleware enabled by default. These routes are stateless and have no session or cross-request memory (one request does not share data or memory with any other request – each is itself encapsulated).
  • console.php These routes correspond to the custom artisan commands you have created for your application.
  • channel.php Registers routes for broadcasting events

The key file to consider at this point is the browser, web.php. By default, one route is already defined, which you take when navigating to the web root of your application (the web directory is in the public directory). For the download application to work, we need three different routes:

  • / upload This will be the URI of the main page that displays our web form for uploading files.
  • / process This will be the place where the form, located in the / upload URI, submits its data submitted by the form (the “action” of the form)
  • / list This will list all files uploaded to the site

Note . The / list endpoint may not be needed if we want to put all the logic for displaying the upload form and the file list on the same page, but I’m keeping them separate for now to add some more stuff to the topic in hand.

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

For each desired route, we explicitly list it in the web.php routes file using one of the available HTTP specific request methods (get (), post (), put (), delete (), patch (), or options ()). For a breakdown of each one . These methods determine which HTTP verbs are allowed to access a given route. If you need a route to be able to accept more than one HTTP verb (which might be the case if you are using a single page to display both the original data and post the submitted form data), you can use the Route :: any () method …

The second argument to Route :: get () and Route :: post () (and any other method associated with the HTTP verb on the Route facade) is the name of the specific controller and the method that is placed inside it. a controller that starts when the route endpoint is reached by an allowed HTTP request (GET, POST, PATCH, etc.). We use UploadController for all three routes and set them like this:

The last method that we call on each route is its name () function, which takes one string as an argument and is used to more or less “mark” a specific route by simply remembering the name (in our cases, load, process and list) … I realize it’s not such a good feature to give each route its own name when the url is exactly the same, but it’s really handy when you have a specific route like / users / profile / dashboard / config, which was would be easier to remember as profile-admin or user-config.

Note on the facades:

  • Facades provide a “static” interface for the classes that are available in the application’s service container. “
  • They provide a concise, memorable syntax that allows you to use Laravel functions without having to remember long class names that need to be entered or configured manually.

In the above route definitions, we are using the Route facade instead of manually instantiating a new Illuminate / Routing / Router object and calling the appropriate methods on that object. It’s just a shortcut that saves typing. Facades are heavily used throughout the Laravel framework – you can and should become more familiar with them.

Application design: quickly reducing our requirements

In this online tutorial, we will create a very simple application that will only do two things:

  1. handle file uploads from web form
  2. display of previously uploaded files on another page.

For this project, our application will be write-only. This means that the user can only write files and view the list of downloaded files. This application is very simple, but it should serve as a good practice to start developing your Laravel skills and knowledge. Note that I’ve ruled out any modeling, migration, and database authentication for brevity, but in a real application these are additional things you’ll want to consider.

Here is a list of the components we need to get the app to work properly:

    • A route that will allow the outside world (Internet) to use the application, and also specify an endpoint that will indicate where the logic for saving the downloaded file is located
  • The controller that handles the response stream request
  • The template that will be used to display a list of previously uploaded files and the actual upload form itself
  • Request for what the controller will use to validate the data submitted from the web form


How to download and install Laravel using Composer

 It assumes that a copy of PHP is already installed on your local system. If not, you can read how to install it here

Composer is a package and dependency manager. To install it, open a terminal and change to a new directory. Run this command:

curl -Ss | php

The results of this command will look like this:

You will see how it downloads and compiles the composer.phar script that we use to install Laravel. While there are many ways to set up a new Laravel application, we will do it using the Laravel Composer script. To install this script, run:

composer global require laravel / installer

Which will look something like this:

This will download and install all the framework files, as well as any dependencies it requires. The packages will be saved in the vendor directory. Once it’s downloaded and installed, you can run the following command:

laravel new uploadApp

You will see something like the following output:

Composer installs all the packages that Laravel needs to run. This may take a few minutes, so please be patient. When finished, run ls -al to see what has been installed.

Here’s a quick breakdown of directories in a typical Laravel application:

  • app /: This is the source folder where our application code lives. All controllers, policies and models are in this folder
  • bootstrap /: contains the application startup script and some classmap files
  • config /: Contains application configuration files. They are usually not directly modified, but instead rely on the values ​​set in the .env (environment) file at the root of the application.
  • database /: contains database files including migrations, seeds and test factories
  • public /: a public folder containing the compiled resources and of course the index.php file
  • resources /: contains external resources such as JavaScript files, language files, CSS / SASS files and all templates used in the application (so called blade templates)
  • routes /: all routes in the app are inside here. There are several different “scopes” of routes, but we will focus on the web.php file.
  • storage /: All temporary cache files used by the application, session files, compiled view scripts, and log files.
  • tests /: Contains test files for the application, such as unit tests and functional tests.
  • vendor /: all dependency packages installed with composer

Now, let’s create the rest of the application and run it with a dedicated artisan command (to save ourselves the hassle of installing and configuring a web server like Apache or nginx). The .env file contains all the configuration values ​​that the files in the / config directory use to configure the application. Internally, you will notice that the configuration value for various parameters is used internally by the application.