Laravel
Requirements
-
Ubuntu 24.04
-
PHP 8
sudo apt install -y php8.3 php8.3-mysql -
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 shopcd /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()
{
$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
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>
<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
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/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
- PHP Laravel 5 Project Example for Beginners
- Building Your First Laravel 10 CRUD Application in Under 30 Minutes
- laravel-best-practices
- 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