Create your First Application with Laravel

By Posted on 15957 views

Since it’s initial launch in 2011, Laravel has experienced exponential growth. In 2015 it became the most outstanding PHP framework in GitHUb.

Laravel’s philosophy is to develop PHP code in an elegant and simple way based on a model MVC (Model-View-Controller). It has a modular and extensible code through a package manager and robust support for database management.

This guide is elaborated thinking in people who are starting with Laravel, a registration system will be developed to cover the basic operations of create, read, update and delete records, commonly known as CRUD.

Server Requirements

All the requirements of the server for the development of this guide are in the article Install Laravel with Apache and MySQL

Create Database

Execute the following command in the terminal:

mysql -u root -p

It will ask you for the password of the root user, once you enter the password correctly it will show you the mysql prompt>

Starting MySQL from the command line
Starting MySQL from the command line

You can also use phpmyadmin to create the database, if you have it installed.

From the terminal create the database to use:

CREATE DATABASE laravelcrud;

Create the username and password, which will be assigned to the created database:

CREATE USER 'laravel_user'@'127.0.0.1' IDENTIFIED BY 'LaB_101

Assign the created user to the database:

GRANT ALL ON laravelcrud.* TO 'laravel_user'@'127.0.0.1';

To reload the privilege table, the following command is executed:

FLUSH PRIVILEGES;

Create Laravel Project

Execute the command that will create a new project called laravelcrud, this command will generate the entire structure of folders, files and dependencies necessary to run the application:

laravel new laravelcrud
Create new Laravel project
Create new Laravel project

Open The Project in the Preference Editor

Once the new Laravel project is generated, open it in your  preferred editor, personally I like to use Visual Code.

Through the terminal access to the project folder:

cd laravelcrud

Set Database Configuration

Search the .env file and proceed to write the configuration of the database created and that will be used by the application:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelcrud
DB_USERNAME=laravel_user
DB_PASSWORD=LaB_101$

To be sure that there is a connection between our application and the database, execute the command:

php artisan migrate

This command will create 3 tables in the default database:

  1. migratios
  2. password_resets
  3. users

In the terminal connected to the MySQL prompt run:

mysql> use laravelcrud;
mysql> show tables;

Additional in the project the migrations for those tables were automatically created in the generated folder app -> database-> migrations

Create Model and Migration

In the terminal execute:

php artisan make:model Registry -m

Two files will be created:

  1. Registry.php the model.
  2. create_registries_table.php the migration.

You need to create the structure (schema) of the registry table to modify the newly created migration file found in app -> database -> migrations -> create_registries_table.ph

In the class created for the migration, the methods up and down are automatically generated, modifying as follows:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateRegistriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('registries', function (Blueprint $table) {
           
            $table->integer('id')->unsigned();
            $table->string('first_name',50);
            $table->string('second_name',50)->nullable();
            $table->string('surename',50);
            $table->string('second_surename',50)->nullable();
            $table->string('email',100);
            $table->string('cell_phone',50)->nullable();
            $table->string('phone',50)->nullable();
            $table->string('coments',500)->nullable();
            $table->integer('age');
            $table->boolean('flosspainfo')->nullable();
            $table->boolean('fedorainfo')->nullable();
            $table->boolean('latansecinfo')->nullable();

            $table->timestamps();
            $table->primary(array('id', 'email'));

            
        });

        DB::statement('ALTER TABLE registries MODIFY id INTEGER NOT NULL AUTO_INCREMENT');
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('registries');
    }
}

Re-execute the migration command:

php artisan migrate

To validate the creation of the table run the database command used previously and to validate the creation of the columns run in the terminal:

use laravelcrud;
show columns from registries;

Create The Register View

The first view is generated, to do this create the registries folder inside app -> resources -> views and then create the create.blade.php file inside this folder:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>FLOSSPA Asistencia Evento </title>
    <link rel="stylesheet" href="{{asset('css/app.css')}}">
    <link rel="stylesheet" href="{{asset('css/registry.css')}}">
    

  </head>
  <body>
    <div class="container">
    <img alt="FLOSSPA" srcset="{{ URL::to('/images/logo-flosspa.svg') }}">
    
    @if ($errors->any())
      <div class="alert alert-danger">
          <ul>
              @foreach ($errors->all() as $error)
                  <li>{{ $error }}</li>
              @endforeach
          </ul>
      </div><br />
      @endif
      @if (\Session::has('success'))
      <div class="alert alert-success">
          <p>{{ \Session::get('success') }}</p>
      </div><br />
      @endif

    <form method="post" action="{{url('registries')}}" id="formRegistry">
    {{csrf_field()}}
        <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Primer Nombre:</label>
            <input type="text" class="form-control" name="first_name"  value={{old('first_name')}}>
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Segundo Nombre:</label>
            <input type="text" class="form-control" name="second_name" value={{old('second_name')}}>
          </div>
        </div>

         <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Primer Apellido:</label>
            <input type="text" class="form-control" name="surename" value={{old('surename')}}>
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Segundo Apellido:</label>
            <input type="text" class="form-control" name="second_surename" value={{old('second_surename')}}>
          </div>
        </div>

        <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Email:</label>
            <input type="text" class="form-control" name="email"  value={{old('email')}}>
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Edad:</label>
            <input type="text" class="form-control" name="age" value={{old('age')}}>
          </div>
        </div>

        <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Télefono Residencial:</label>
            <input type="text" class="form-control" name="phone" value={{old('phone')}}> 
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Celular:</label>
            <input type="text" class="form-control" name="cell_phone" value={{old('cell_phone')}}>
          </div>
        </div>

        <div class="row">
        
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
          <label for="name">Desea recibir información de:</label>
          <div class="checkbox">
          
            <label> <input type="checkbox" name="flosspainfo" @if(old('flosspainfo') !== NULL ){{ 'checked' }}@endif> FLOSSPA</label>
          </div>
          <div class="checkbox">
            <label> <input type="checkbox" name="fedorainfo" @if(old('fedorainfo') !== NULL ){{ 'checked' }}@endif> FEDORA</label>
          </div>
          <div class="checkbox disabled">
            <label> <input type="checkbox" name="latansecinfo" @if(old('latansecinfo') !== NULL ){{ 'checked' }}@endif> LATANSEC</label>
          </div>
          </div>
          
        </div>
        
        <div class="row">
          <div class="form-group col-xs-12 col-sm-12 col-md-12">
            <label for="name">Comentarios:</label>
            <textarea class="form-control" rows="5" name="coments" >{{old('coments')}}</textarea>
          </div>
        </div>

        <div class="row">
          
          <div class="form-group col-xs-12 col-sm-12 col-md-12">
            <button type="submit" class="btn btn-success">Agregar Asistencia</button>
          </div>
        </div>
      </form>
    </div>
    <div id="toast-container" class="toast-top-right">
    </div
  </body>
</html>

To avoid CSRF attacks (Cross-site request forgery or cross-site request forgery) is a type of malicious exploit of a website in which unauthorized commands are transmitted by a user in which the website trusts. This vulnerability is also known by other names such as XSRF, hostile link, session thrust, and automatic attack. Larvel provides the protection {{csrf_field ()}}.

To preserve the information in the form, it is achieved by adding value = {{old (‘first_name’)}} in each of the added controls.

Now create the route to display the view, execute the following command:

php artisan make:controller RegistryController --resource

Inside the folder app -> Http -> Controllers you will find the controller, automatically generated with all the necessary methods for the CRUD.

In order to have access to the methods created, a route referring to the controller must be added, the file app -> routes -> web.php is modified

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/


Route::resource('registries','RegistryController');

To watch the list of routes execute in the terminal:

php artisan route:list

In the create method of the controller, the following code is added:

public function create()
{  
   return view('registries.create');
}

Start the Laravel development server and you will watch the first view:

php artisan serve

Load the next URL in the browser:

http://localhost:8000/registries/create

Laravel application view
Laravel application view

In the public -> css folder, custom CSS was added and the images folder was created to add the image that is displayed on the screen. You can download the code from my GitHub account.

In the model, you must handle the Mass Assignment vulnerability, the class found in app -> Registry.php is modified.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Registry extends Model
{
   
    protected $fillable = ['first_name','second_name','surename','second_surename',
                        'email','age','phone','cell_phone','flosspainfo','fedorainfo','latansecinfo','coments']; 
}

For to save the data that is sent from the view, the RegistryController.php controller must be modified, including the Registry class and the static interface (Facades) Input.

use App\Registry;
use Illuminate\Support\Facades\Input;

Now you must modify the store method:

public function store(Request $request)
    {
       
        $registry = $this->validate(request(), [
            'first_name' => 'required',
            'surename' => 'required',
            'email' => 'required|email',
            'age' => 'integer|min:0'
          ]);

        
          $flosspainfo = Input::get('flosspainfo') == 'on' ? true :false;
          $fedorainfo = Input::get('fedorainfo') == 'on' ? true :false;
          $latansecinfo = Input::get('latansecinfo') == 'on' ? true :false;
          

          Registry::create([
            'first_name'=> Input::get('first_name'),
            'second_name'=> Input::get('second_name'),
            'surename'=> Input::get('surename'),
            'second_surename'=> Input::get('second_surename'),
            'email'=> Input::get('email'),
            'cell_phone' => Input::get('cell_phone'),
            'phone'=> Input::get('phone'),
            'coments'=> Input::get('coments'),
            'age'=> Input::get('age'),
            'flosspainfo'=> $flosspainfo,
            'fedorainfo'=>  $fedorainfo,
            'latansecinfo'=>  $latansecinfo
          ]);
  
          return back()->with('success', 'Información almacenada con éxito');
    }

Load the view and try to save without filling the data, validation messages will be received.

To display the messages in Spanish you can use the following translation package.

List View

Now you will create a list of all saved records, create the view in

app–>resources–>views–> registries–>index.blade.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Index Page</title>
    <link rel="stylesheet" href="{{asset('css/app.css')}}">
  </head>
  <body>
    <div class="container">
    <img src="equilateral.png" alt="FLOSSPA" srcset="{{ URL::to('/images/logo-flosspa.svg') }}">
    <br />
    @if (\Session::has('success'))
      <div class="alert alert-success">
        <p>{{ \Session::get('success') }}</p>
      </div><br />
     @endif
    <table class="table table-striped">
    <thead>
      <tr>
        <th>ID</th>
        <th>Nombre</th>
        <th>Apellido</th>
        <th >Email</th>
        <th >Teléfono</th>
        <th >Celular</th>
        <th colspan="2">Acción</th>
      </tr>
    </thead>
    <tbody>
      @foreach($registries as $registry)
      <tr>
        <td>{{$registry['id']}}</td>
        <td>{{$registry['first_name']}}</td>
        <td>{{$registry['surename']}}</td>
        <td>{{$registry['email']}}</td>
        <td>{{$registry['phone']}}</td>
        <td>{{$registry['cell_phone']}}</td>
        <td><a href="{{action('RegistryController@edit', $registry['id'])}}" class="btn btn-warning">Edit</a></td>
        <td>
          <form  onsubmit="return confirm('Do you really want to delete?');" action="{{action('RegistryController@destroy', $registry['id'])}}" method="post">
            {{csrf_field()}}
            <input name="_method" type="hidden" value="DELETE">
            <button class="btn btn-danger" type="submit">Delete</button>
          </form>
        </td>
      </tr>
      @endforeach
    </tbody>
  </table>
  </div>
  </body>
</html

Modify the controller by adding the view load:

public function index()
{
    $registries = Registry::all()->toArray();
    return view('registries.index', compact('registries'));
}

Load the view http://localhost:8000/registries

View of the list of records
View of the list of records

Edit View

Create the editing functionality of a record, for it starts creating the view that is quite similar to that of the creation app -> resources -> views -> registries -> edit.blade.php

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>FLOSSPA Editar Asistencia Evento </title>
    <link rel="stylesheet" href="{{asset('css/app.css')}}">
    <link rel="stylesheet" href="{{asset('css/registry.css')}}">
    

  </head>
  <body>
    <div class="container">
    <img src="equilateral.png" alt="FLOSSPA" srcset="{{ URL::to('/images/logo-flosspa.svg') }}">
    
    @if ($errors->any())
      <div class="alert alert-danger">
          <ul>
              @foreach ($errors->all() as $error)
                  <li>{{ $error }}</li>
              @endforeach
          </ul>
      </div><br />
      @endif
      @if (\Session::has('success'))
      <div class="alert alert-success">
          <p>{{ \Session::get('success') }}</p>
      </div><br />
      @endif

    <form method="post" action="{{action('RegistryController@update', $id)}}" id="formRegistry">
    {{csrf_field()}}
    <input name="_method" type="hidden" value="PATCH">
        <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Primer Nombre:</label>
            <input type="text" class="form-control" name="first_name"  value="{{$registry->first_name}}" >
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Segundo Nombre:</label>
            <input type="text" class="form-control" name="second_name" value="{{$registry->second_name}}">
          </div>
        </div>

         <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Primer Apellido:</label>
            <input type="text" class="form-control" name="surename" value="{{$registry->surename}}">
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Segundo Apellido:</label>
            <input type="text" class="form-control" name="second_surename" value="{{$registry->second_surename}}">
          </div>
        </div>

        <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Email:</label>
            <input type="text" class="form-control" name="email"  value="{{$registry->email}}">
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Edad:</label>
            <input type="text" class="form-control" name="age" value="{{$registry->age}}">
          </div>
        </div>

        <div class="row">
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Télefono Residencial:</label>
            <input type="text" class="form-control" name="phone" value="{{$registry->phone}}"> 
          </div>
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
            <label for="name">Celular:</label>
            <input type="text" class="form-control" name="cell_phone" value="{{$registry->cell_phone}}">
          </div>
        </div>

        <div class="row">
        
          <div class="form-group col-xs-12 col-sm-6 col-md-6">
          <label for="name">Desea recibir información de:</label>
          <div class="checkbox">
          
            <label> <input type="checkbox" name="flosspainfo" @if($registry->flosspainfo == true ){{ 'checked' }}@endif> FLOSSPA</label>
          </div>
          <div class="checkbox">
            <label> <input type="checkbox" name="fedorainfo" @if($registry->fedorainfo == true){{ 'checked' }}@endif> FEDORA</label>
          </div>
          <div class="checkbox disabled">
            <label> <input type="checkbox" name="latansecinfo" @if($registry->latansecinfo == true ){{ 'checked' }}@endif> LATANSEC</label>
          </div>
          </div>
          
        </div>
        
        <div class="row">
          <div class="form-group col-xs-12 col-sm-12 col-md-12">
            <label for="name">Comentarios:</label>
            <textarea class="form-control" rows="5" name="coments" >{{$registry->coments}}</textarea>
          </div>
        </div>

        <div class="row">
          
          <div class="form-group col-xs-12 col-sm-12 col-md-12">
            <button type="submit" class="btn btn-success">Update</button>
          </div>
        </div>
      </form>
    </div>
    <div id="toast-container" class="toast-top-right">
    </div
  </body>
</html>

Modify the edit method, as well as the update method of the controller:

/**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $registry = Registry::find($id);
        return view('registries.edit',compact('registry','id'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
      
       $registry = Registry::find($id);
        $this->validate(request(), [
            'first_name' => 'required',
            'surename' => 'required',
            'email' => 'required|email',
            'age' => 'integer|min:0'
          ]);

        
          $registry->first_name = Input::get('first_name');
          $registry->second_name =  Input::get('second_name');
          $registry->surename = Input::get('surename');
          $registry->second_surename =  Input::get('second_surename');
          $registry->email = Input::get('email');
          $registry->cell_phone =  Input::get('cell_phone');
          $registry->phone = Input::get('phone');
          $registry->coments = Input::get('coments');
          $registry->age = Input::get('age');
          $registry->flosspainfo = Input::get('flosspainfo') == 'on' ? true :false;
          $registry->fedorainfo = Input::get('fedorainfo') == 'on' ? true :false;
          $registry->latansecinfo = Input::get('latansecinfo') == 'on' ? true :false;
          $registry->save();
          
  
          return back()->with('success', 'Registry updated successfully');
          
    }

Deleting Record

To delete a record, add the following in the destroy method of the controller:

public function destroy($id)
{
  $registry = Registry::find($id);
  $registry->delete();
  return redirect('registries')->with('success','Registry has been  deleted');
}

You can find the fully functional project in my GitHub account.

What do you think?

Your email address will not be published. Required fields are marked *

12 + 7 =

No Comments Yet.