PHP: Next Steps: Introduction to Laravel
Congratulations on completing 35 lessons of PHP fundamentals! You've built your own router, controllers, views, and models—isn't that essentially a mini framework? Laravel does all of this 10x more elegantly. This lesson is your bridge from hand-written PHP to a modern framework.
1. Why Do We Need a Framework?
The blog system you built in PHP has already run into these pain points:
| Your Pain Point | Framework Solution |
|---|---|
| URL rewriting with .htaccess is a hassle | Laravel's built-in routing: Route::get('/posts', ...) |
| Every page needs session_start + auth checks | Middleware: ->middleware('auth') |
| Hand-written SQL is error-prone; switching databases is hard | Eloquent ORM: Post::all() |
| Manually require all files | Composer autoloading |
| DIY CSRF protection in forms | @csrf — one line |
| Manual database changes | Migrations for version control |
| Repeated password hashing code | Hash::make(), Auth::attempt() |
2. Installing Laravel
# Create a new project
composer create-project laravel/laravel myblog
# Start the development server
cd myblog
php artisan serve
# Open http://localhost:8000
myblog/ ← Laravel project
├── app/
│ ├── Models/ ← Eloquent models
│ │ └── Post.php
│ └── Http/
│ └── Controllers/ ← Controllers
│ └── PostController.php
├── routes/
│ └── web.php ← Routes (core!)
├── resources/
│ └── views/ ← Blade templates
│ └── posts/
├── database/
│ └── migrations/ ← Database migrations
├── .env ← Environment configuration
└── artisan ← CLI toolkit
3. Routing — Your Hand-Built Router vs. Laravel
(1) What you built by hand:
$router->add('GET', '/posts', [$ctrl, 'index']);
$router->add('GET', '/posts/{id}', [$ctrl, 'show']);
(2) Laravel's version:
// routes/web.php
use App\Http\Controllers\PostController;
Route::get('/posts', [PostController::class, 'index']);
Route::get('/posts/{id}', [PostController::class, 'show']);
// Even cleaner: resource routing (one line generates 7 standard routes)
Route::resource('posts', PostController::class);
// List all routes
// php artisan route:list
4. Eloquent ORM — Your Hand-Built Model vs. Laravel
(1) What you built by hand:
// ~30 lines of CRUD code
public function getAll(): array { ... }
public function findById(int $id): ?array { ... }
public function create(...): int { ... }
(2) Laravel's version:
<?php
// app/Models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// That's it! Laravel automatically maps to the posts table
protected $fillable = ['title', 'content', 'user_id'];
// Relationship with users
public function user()
{
return $this->belongsTo(User::class);
}
}
// Usage (10 lines of hand-written code → 1 line)
$posts = Post::all();
$post = Post::find(1);
Post::create(['title' => 'Hello', 'content' => 'World', 'user_id' => 1]);
$post->update(['title' => 'New Title']);
$post->delete();
// Relationship query
echo $post->user->username; // Automatically JOINs the users table
?>
5. Blade Templates — Your Hand-Built PHP View vs. Blade
(1) What you built by hand:
<?php foreach ($posts as $post): ?>
<h2><?= htmlspecialchars($post['title']) ?></h2>
<?php endforeach; ?>
▶ Example: Blade Post List Template
Output:
<h2>All Posts</h2>
<div class="post-card">
<h2><a href="/posts/1">Post Title</a></h2>
<p>Post content preview...</p>
</div>
<!-- Pagination links -->
{{-- resources/views/posts/index.blade.php --}}
@extends('layouts.app')
@section('content')
<h2>All Posts</h2>
@foreach ($posts as $post)
<div class="post-card">
<h2><a href="/posts/{{ $post->id }}">{{ $post->title }}</a></h2>
<p>{{ Str::limit($post->content, 200) }}</p>
</div>
@endforeach
{{-- Pagination links auto-generated! --}}
{{ $posts->links() }}
@endsection
Output:
<!DOCTYPE html>
<html><head><title>Post Title - MyBlog</title></head>
<body>
<nav>Home | Posts</nav>
<h1>Post Title</h1>
<p>By John - Jan 15, 2025</p>
<div>Post content...</div>
<form method="POST" action="/posts/1">
<button>Delete Post</button>
</form>
</body></html>
Blade features:
{{ $var }}auto-applieshtmlspecialchars(XSS protection)@if @else @endif/@foreach @endforeach— cleaner syntax@extends/@section— template inheritance@csrf— automatically generates a CSRF token hidden field
6. Migrations — Managing Database Structure
No more manually executing SQL to create tables. Define your table structure in code:
# Create a migration file
php artisan make:migration create_posts_table
# Run migrations
php artisan migrate
# Rollback
php artisan migrate:rollback
<?php
// database/migrations/xxx_create_posts_table.php
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('title');
$table->text('content');
$table->timestamps(); // created_at + updated_at auto-managed
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
php artisan migrate:rollback rolls back just like Git; (2) Team collaboration—everyone runs the same migrations and gets the same table structure; (3) Automatic handling of field names, types, indexes, and foreign keys.
7. Authentication System — 50 Lines by Hand vs. 3 Lines in Laravel
(1) What you built by hand:
// Password verification + Session management + Logout + Permission checks = ~50 lines
(2) Laravel's version:
# One command generates a complete auth system (login/register/password reset/email verification)
composer require laravel/breeze
php artisan breeze:install blade
php artisan migrate
npm install && npm run build
// Route protection
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware('auth');
// Get the current user
$user = auth()->user();
echo $user->posts; // Auto relationship query
8. Artisan — Your CLI Toolkit
# Create a controller
php artisan make:controller PostController
# Create a model (generates Migration + Factory + Seeder together)
php artisan make:model Post -a
# Database operations
php artisan migrate # Run migrations
php artisan db:seed # Seed test data
php artisan migrate:fresh --seed # Reset database + seed
# Debugging
php artisan route:list # List all routes
php artisan tinker # Interactive PHP REPL (can directly operate on the database)
9. Laravel Blog System — The Complete Version
▶ Example: Complete Laravel Controller
<?php
// routes/web.php
use App\Http\Controllers\PostController;
Route::get('/', [PostController::class, 'index']);
Route::resource('posts', PostController::class)->middleware('auth');
Route::get('/register', [RegisteredUserController::class, 'create']);
Route::post('/register', [RegisteredUserController::class, 'store']);
Output:
(no visible output - class defined)
<?php
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
$posts = Post::with('user')->latest()->paginate(10);
return view('posts.index', compact('posts'));
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:200',
'content' => 'required',
]);
Post::create([
...$validated,
'user_id' => auth()->id(),
]);
return redirect('/posts')->with('success', 'Post published successfully!');
}
}
Compare: Your hand-written blog used ~150 lines for PostController. Laravel uses ~20—and the Laravel version comes with SQL injection prevention, CSRF protection, form validation, and pagination built in.
10. Your PHP Learning Roadmap
✅ You've completed:
Fundamentals (variables, arrays, functions, loops, conditionals)
↓
Web Interaction (forms, cookies, sessions, file uploads) ← 36 lessons done
↓
OOP (classes, inheritance, interfaces, traits, namespaces, Composer)
↓
Database Operations (MySQL, PDO, transactions, security)
↓
PHP 8 Modern Features (enums, match, constructor property promotion)
↓
🔜 Your next steps:
1. Rewrite the blog system in Laravel (this week)
— Internalize the framework mindset, experience the productivity leap
2. Learn REST API development
— JSON responses, frontend-backend separation
3. Explore testing (PHPUnit/Pest)
— Protect your code with automated tests
4. Dive deeper:
— Laravel ecosystem (Eloquent, Queues, Events, Notifications)
— Design patterns (Repository, Service, Factory)
— Performance optimization (Redis caching, N+1 query, Opcache)
▶ Example: Blade Layout and Template Inheritance
Output:
Post published successfully! (redirect to /posts)
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="en">
<head><title>@yield('title', 'MyBlog')</title></head>
<body>
<nav><a href="/">Home</a> | <a href="/posts">Posts</a></nav>
@yield('content')
</body>
</html>
{{-- resources/views/posts/show.blade.php --}}
@extends('layouts.app')
@section('title', $post->title)
@section('content')
<h1>{{ $post->title }}</h1>
<p>By {{ $post->user->name }} — {{ $post->created_at->format('M d, Y') }}</p>
<div>{{ $post->content }}</div>
<form method="POST" action="/posts/{{ $post->id }}">
@method('DELETE')
@csrf
<button type="submit">Delete Post</button>
</form>
@endsection
Output:
<nav>Home | Posts</nav>
<h1>Post Title</h1>
<p>By John - Jan 15, 2025</p>
❓ FAQ
📖 Summary
- Frameworks don't add complexity—they organize existing capabilities
- Laravel:
Route::get()routing →EloquentORM →Bladetemplates →ArtisanCLI Post::all()replaces hand-writtenSELECT * FROM posts@foreachreplaces<?php foreach ?>php artisancommand-line generators boost productivity- You've mastered MVC core concepts—Laravel simply makes MVC more elegant
- Laravel docs: https://laravel.com/docs
- Laravel community: https://laracasts.com
📝 Exercises
- Install Laravel, create a new project, and get
php artisan serverunning to see the welcome page. - Use
php artisan make:model Post -ato create a complete post resource. Write a migration to create the table. Insert some test data using Tinker. - Rewrite your blog system's post list page and post detail page using Laravel (Blade templates + Eloquent queries). Compare the experience with your hand-written version.
🎉 Congratulations on completing 36 lessons of the PHP tutorial! You started knowing nothing about
echoand finished as a developer capable of building complete web applications in PHP, understanding MVC architecture, and mastering database operations and security. The PHP world is vast—WordPress, Laravel, Drupal, Symfony are all waiting for you. Keep going! 🚀