What it is
Laravel is the most popular PHP framework, providing routing, an ORM, queues, caching, authentication, validation and testing in one coherent package.
Routes map to controllers or closures. Eloquent handles the database, Blade the templates, and artisan the command line. Convention covers most decisions.
Installation
composer create-project laravel/laravel my-appGetting started
The smallest useful thing you can do with it, and what each part means.
<?php
Route::get('/books/{book}', function (Book $book) {
return $book->load('author'); // route model binding: 404 automatic
});
Route::post('/books', function (Request $request) {
$validated = $request->validate([
'title' => ['required', 'string', 'max:200'],
'year' => ['required', 'integer', 'between:1400,2100'],
'isbn' => ['nullable', 'string', 'unique:books,isbn'],
]);
return Book::create($validated); // 422 with errors if validation failed
});<?php
class Book extends Model
{
protected $fillable = ['title', 'year', 'author_id'];
protected $casts = ['published_at' => 'datetime'];
public function author(): BelongsTo { return $this->belongsTo(Author::class); }
public function reviews(): HasMany { return $this->hasMany(Review::class); }
public function scopeRecent(Builder $q): Builder {
return $q->where('year', '>=', now()->year - 5);
}
}
// with() avoids N+1 — one query for books, one for authors.
$books = Book::with('author')->recent()->latest('year')->paginate(20);Advanced usage
Where the library earns its place over a simpler alternative.
<?php
class ProcessImport implements ShouldQueue
{
use Queueable;
public int $tries = 3;
public int $backoff = 60;
public function __construct(public int $importId) {}
public function handle(ImportService $service): void
{
DB::transaction(function () use ($service) {
$service->run($this->importId);
});
}
}
ProcessImport::dispatch($import->id)->onQueue('imports');
// Only dispatch after the transaction actually commits.
DB::transaction(function () use ($order) {
$order->save();
OrderPlaced::dispatch($order); // Laravel defers this with afterCommit
});Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- SQLSTATE[42S22]: Column not found
- A migration has not run, or a column was renamed. Run php artisan migrate and check the model's $fillable and $casts.
- Target class does not exist
- A controller namespace or class name is wrong. Run composer dump-autoload after moving files.
Best practices
- Always eager load relations you will access; enable preventLazyLoading in development to catch N+1 early.
- Pass ids to queued jobs, not models, so the worker reads current data.
- Use form request classes for anything beyond trivial validation.
- Never disable mass-assignment protection; keep $fillable accurate.
Background
Why it exists, and what it was reacting to.
Created by Taylor Otwell in 2011, Laravel combined Symfony's components with an API designed for developer experience. Its documentation and first-party ecosystem are a large part of why it dominates modern PHP.
