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
    
    File 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
    
    File 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
    
    File Content
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Models\Product;
    
    class ProductController extends Controller
    {
        public function index()
        {
            // Fetch all products from DB.
            $products = Product::all();
    
            return view('product.list', ['products' => $products]);
        }
    
        public function show(int $product_id)
        {
            return view('product.show', ['product' => Product::find($product_id)]);
        }
    
        public function create()
        {
            return view('product.add');
        }
    
        public function store(Request $request)
        {
            $newProduct = Product::create([
                'title' => $request->title,
                'descript' => $request->descript,
                'price' => $request->price
            ]);
    
            return redirect('/products');
        }
    
        public function edit(int $product_id)
        {
            return view('product.edit', ['product' => Product::find($product_id)]);
        }
    
        public function update(int $product_id, Request $request)
        {
            Product::find($product_id)->update([
                'title' => $request->title,
                'descript' => $request->descript,
                'price' => $request->price
            ]);
    
            return redirect('/products/' . $product_id);
        }
    
        public function destroy(int $product_id)
        {
            Product::find($product_id)->delete();
            return redirect('/products');
        }
    }
    
  • Define view

    sudo -u www-data mkdir resources/views/product
    
    sudo -u www-data vim resources/views/product/list.blade.php
    
    File 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>
    
                @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><a href="/products/{{ $product->id }}">{{ $product->title }}</a></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
                                            <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
    
                <br />
    
                <a href="/products/create" class="btn btn-primary mb-3">Add a Product</a>
            </div>
        </body>
    </html>
    
    sudo -u www-data vim resources/views/product/show.blade.php
    
    File Content
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Product ListShow</title>
            <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    
            <style>
    
                table
                {
                    border-collapse: collapse;
                }
    
                table th,
                table td
                {
                    padding: 5px 10px;
                    border: 1px solid #000000;
                    text-align: left;
                }
    
            </style>
        </head>
        <body>
            <div class="container">
                <h1>Product Show</h1>
    
                <table>
                    <tr>
                        <th>ID</th>
                        <td>{{ $product->id }}</td>
                    </tr>
    
                    <tr>
                        <th>Title</th>
                        <td>{{ $product->title }}</td>
                    </tr>
    
                    <tr>
                        <th>Description</th>
                        <td>{{ $product->descript }}</td>
                    </tr>
    
                    <tr>
                        <th>Price</th>
                        <td>{{ $product->price }}</td>
                    </tr>
                </table>
    
                <br />
    
                <a href="/products">Back to list</a>
            </div>
        </body>
    </html>
    
    sudo -u www-data vim resources/views/product/add.blade.php
    
    File Content
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Product ListAdd</title>
            <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    
            <style>
    
                input
                {
                    margin: 5px 0px;
                    padding: 5px;
                }
    
            </style>
        </head>
        <body>
            <div class="container">
                <h1>Product Add</h1>
    
                <form method="post" action="/products/create">
                    @csrf
                    <input type="text" name="title" placeholder="Title" /><br />
                    <input type="text" name="descript" placeholder="Description" /><br />
                    <input type="text" name="price" placeholder="Price" /><br />
    
                    <input type="submit" value="Add" />
                </form>
            </div>
    
            <br />
    
            <a href="/products">Back to list</a>
        </body>
    </html>
    
    sudo -u www-data vim resources/views/product/edit.blade.php
    
    File Content
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Product ListEdit</title>
            <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    
            <style>
    
                input
                {
                    margin: 5px 0px;
                    padding: 5px;
                }
    
            </style>
        </head>
        <body>
            <div class="container">
                <h1>Product AddEdit</h1>
    
                <form method="post" action="/products/{{ $product->id }}/edit">
                    @csrf
                    <input type="text" name="title" placeholder="Title" value="{{ $product->title }}" /><br />
                    <input type="text" name="descript" placeholder="Description" value="{{ $product->descript }}" /><br />
                    <input type="text" name="price" placeholder="Price" value="{{ $product->price }}" /><br />
    
                    <input type="submit" value="Edit" />
                </form>
            </div>
    
            <br />
    
            <a href="/products">Back to list</a>
        </body>
    </html>
    
  • Define router

    sudo -u www-data vim routes/web.php
    
    File 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/{id}', [ProductController::class, 'show']);
    Route::get('/products/create', [ProductController::class, 'create']);
    Route::post('/products/create', [ProductController::class, 'store']);
    Route::get('/products/{id}/edit', [ProductController::class, 'edit']);
    Route::post('/products/{id}/edit', [ProductController::class, 'update']);
    Route::post('/products/{id}', [ProductController::class, 'destroy']);
    

Reference