Skip to main content

Laravel

Requirements

  • Ubuntu 24.04

  • PHP 8

    sudo apt install -y php8.3 php8.3-mysql
    
  • composer

    sudo apt install -y composer
    
  • mariadb

    sudo apt install -y mariadb-server
    

Example

  • Setup Apache2

    sudo vim /etc/apache2/apache2.conf
    
    # <Directory /var/www/Websites>
    #     Options Indexes FollowSymLinks
    #     AllowOverride All
    #     Require all granted
    # </Directory>
    
    sudo a2enmod rewrite
    sudo systemctl reload apache2
    
    # Create virtual host config file.
    sudo vim /etc/apache2/sites-available/shop.conf
    
    # <VirtualHost *:80>
    # 	  DocumentRoot /var/www/Websites/shop/public
    # </VirtualHost>
    
    sudo systemctl reload apache2
    
  • Create project

    cd /var/www/Websites/
    sudo -u www-data composer create-project laravel/laravel:10 shop
    
    cd /var/www/Websites/shop/
    
  • Edit environment variables

    # Create database user and database in advanced.
    # Set database basic information.
    sudo -u www-data vim .env
    sudo systemctl reload apache2
    
  • Create model (with migration) & controller

    # Create model with controller and migration.
    sudo -u www-data php artisan make:model -c -m Product
    
  • Define model

    sudo -u www-data vim app/Models/Product.php
    
    • Content

      <?php
      
      namespace App\Models;
      
      use Illuminate\Database\Eloquent\Factories\HasFactory;
      use Illuminate\Database\Eloquent\Model;
      
      class Product extends Model
      {
        use HasFactory;
      
        protected $fillable = ['title', 'descript', 'price'];
      }
      
  • Define migration according to model

    sudo -u www-data vim database/migrations/2024_09_09_082148_create_products_table.php
    
    • Content

      <?php
      
      use Illuminate\Database\Migrations\Migration;
      use Illuminate\Database\Schema\Blueprint;
      use Illuminate\Support\Facades\Schema;
      
      return new class extends Migration
      {
          /**
           * Run the migrations.
           */
          public function up(): void
          {
              Schema::create('products', function (Blueprint $table) {
                  $table->id();
                  $table->text('title');
                  $table->text('descript');
                  $table->unsignedInteger('price');
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           */
          public function down(): void
          {
              Schema::dropIfExists('products');
          }
      };
      
  • Do migrate to create table in database

    sudo -u www-data php artisan migrate
    sudo -u www-data php artisan migrate:status
    
  • Define controller

    sudo -u www-data vim app/Http/Controllers/ProductController.php
    
    • Content

      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use App\Models\Product;
      
      class ProductController extends Controller
      {
          public function index()
          {   
              $products = Product::all(); //fetch all products from DB
              return view('product.list', ['products' => $products]);
          }   
      
          public function create()
          {   
              return view('product.add');
          }   
      
          public function store(Request $request)
          {   
              $newPost = Product::create([
                  'title' => $request->title,
                  'short_notes' => $request->short_notes,
                  'price' => $request->price
              ]);
      
              return redirect('product/' . $newPost->id . '/edit');
          }   
      
          public function show(Product $product)
          {   
              //
          }   
      
          public function edit(Product $product)
          {   
              return view('product.edit', [
                  'product' => $product,
              ]);
          }   
      
          public function update(Request $request, Product $product)
          {   
              $product->update([
                  'title' => $request->title,
                  'short_notes' => $request->short_notes,
                  'price' => $request->price
              ]);
      
              return redirect('product/' . $product->id . '/edit');
          }   
      
          public function destroy(Product $product)
          {   
              $product->delete();
              return redirect('product/');
          }   
      }
      
  • Define view

    sudo -u www-data mkdir resources/views/product
    
    sudo -u www-data vim resources/views/product/list.blade.php
    
    • Content

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Product List</title>
              <link rel="stylesheet" href="{{ asset('css/app.css') }}">
      
              <style>
      
                  table
                  {
                      border-collapse: collapse;
                  }
      
                  th, td
                  {
                      padding: 5px 10px;
                      border: 1px solid #000000;
                  }
      
              </style>
          </head>
          <body>
              <div class="container">
                  <h1>Product List</h1>
      
                  <a href="/products/create" class="btn btn-primary mb-3">Add New Product</a>
      
                  @if ($products->isEmpty())
                      <p>No content available.</p>
                  @else
                      <table class="table table-bordered">
                          <thead>
                              <tr>
                                  <th>ID</th>
                                  <th>Title</th>
                                  <th>Description</th>
                                  <th>Price</th>
                                  <th>Actions</th>
                              </tr>
                          </thead>
                          <tbody>
                              @foreach ($products as $product)
                                  <tr>
                                      <td>{{ $product->id }}</td>
                                      <td>{{ $product->title }}</td>
                                      <td>{{ $product->descript }}</td>
                                      <td>{{ $product->price }}</td>
                                      <td>
                                          <a href="/products/{{ $product->id }}/edit" class="btn btn-warning btn-sm">Edit</a>
                                          <form action="/products/{{ $product->id }}" method="POST" style="display:inline;">
                                              @csrf
                                              @method('DELETE')
                                              <button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this product?')">Delete</button>
                                          </form>
                                      </td>
                                  </tr>
                              @endforeach
                          </tbody>
                      </table>
                  @endif
              </div>
          </body>
      </html>
      
  • Define router

    sudo -u www-data vim routes/web.php
    
    • Content

      <?php
      
      use Illuminate\Support\Facades\Route;
      use App\Http\Controllers\ProductController;
      
      /*
      |--------------------------------------------------------------------------
      | Web Routes
      |--------------------------------------------------------------------------
      |
      | Here is where you can register web routes for your application. These
      | routes are loaded by the RouteServiceProvider and all of them will
      | be assigned to the "web" middleware group. Make something great!
      |
      */
      
      Route::get('/', function () { return view('welcome'); }); 
      Route::get('/products', [ProductController::class, 'index']);
      Route::get('/products/create', [ProductController::class, 'create']);
      Route::post('/products/create', [ProductController::class, 'store']);
      Route::get('/products/{id}', [ProductController::class, 'show']);
      Route::get('/products/{id}/edit', [ProductController::class, 'edit']);
      Route::put('/products/{id}', [ProductController::class, 'update']);
      Route::post('/products/{id}', [ProductController::class, 'destroy']);
      

Reference


  • Mapping between ROUTE and REQUEST

    Method Path Function Form Description
    GET /products index() UI List all
    GET /products/create create() UI Add one
    POST /products/create store() API Add one
    GET /products/{product} show() UI Show one
    GET /products/{product}/edit edit() UI Edit one
    PUT /products/{product} update() API Edit one
    POST /products/{product} destroy() API Delete one