Skip to content

laravel_quick_guide

Laravel is a web application framework with expressive, elegant syntax. It adheres to the MVC (Model-View-Controller) architectural pattern and provides a vast ecosystem of tools and features like a powerful ORM (Eloquent), database migrations, a robust routing system, an integrated testing suite, and the Artisan command-line interface. Laravel aims to make common web development tasks, such as authentication, routing, sessions, and caching, easier and faster.

Being an open-source framework, Laravel benefits from a large community and offers a rich set of features that significantly boost web development speed and quality. For developers familiar with PHP, Laravel provides a structured and efficient way to build applications, reducing boilerplate code and enhancing security by mitigating common web vulnerabilities.

  • Eloquent ORM: An advanced ActiveRecord implementation for easy database interaction.
  • Routing System: Simple and expressive way to define application routes.
  • Blade Templating Engine: A powerful, yet simple templating language.
  • Migrations & Seeding: Version control for your database schema and easy data population.
  • Artisan Console: A command-line interface with helpful commands for common tasks.
  • Testing: Built-in support for unit and feature testing with PHPUnit.
  • Modularity & Composer: Easy dependency management and package integration.
  • Security: Protection against common web vulnerabilities like XSS, CSRF, and SQL injection.
  • Task Scheduling: A fluent API for scheduling recurring tasks.
  • Queues: For deferring time-consuming tasks to background processing.
  • Broadcasting & WebSockets: For building real-time applications.
  • Authentication & Authorization: Simplified setup for user login, registration, and access control.

Laravel uses Composer for dependency management. Ensure Composer is installed on your system before proceeding.

Download and install Composer from https://getcomposer.org/download/. Verify installation with composer --version.

Use Composer to create a new Laravel project:

composer create-project laravel/laravel example-app

Replace example-app with your project’s name. This downloads Laravel and its dependencies.

Navigate into your project directory (cd example-app) and start the Artisan development server:

php artisan serve

This typically starts the server at http://127.0.0.1:8000.

Open http://127.0.0.1:8000 in your browser. You should see the Laravel welcome page.

For detailed system requirements and alternative installation methods like Laravel Sail (Docker), refer to the Laravel Installation Guide section.

The root directory of a Laravel application contains several key folders:

  • app - Contains the core code of your application (Models, Controllers, Service Providers, etc.).
  • bootstrap - Contains files that bootstrap the framework and configure autoloading, plus a cache directory for framework-generated files.
  • config - Contains all of your application’s configuration files.
  • database - Contains your database migrations, model factories, and seeders.
  • public - The document root for your application. It contains the index.php entry point and your assets (CSS, JS, images).
  • resources - Contains your views (Blade templates), raw assets (like Sass or Less files if not using Vite/Mix defaults), and language files.
  • routes - Contains all route definitions for your application (e.g., web.php, api.php).
  • storage - Contains compiled Blade templates, file-based sessions, file caches, logs, and other files generated by the framework. Also used for user-uploaded files.
  • tests - Contains your automated tests (feature and unit tests).
  • vendor - Contains your Composer dependencies.

The app directory is where most of your application’s code resides. Key subdirectories include:

  • Console - Contains your custom Artisan commands.
  • Exceptions - Contains your application’s custom exception handler.
  • Http - Contains your Controllers, Middleware, and Form Requests.
  • Jobs - Contains your queueable jobs.
  • Listeners - Contains handler classes for your events.
  • Mail - Contains your mailable classes for sending emails.
  • Models - (Often created by developers, not always default) Contains your Eloquent model classes.
  • Notifications - Contains notification classes.
  • Policies - Contains authorization policy classes.
  • Providers - Contains all of your application’s service providers.

All configuration files for the Laravel framework are stored in the config directory. Each option is documented, so feel free to look through the files and get familiar with the options available to you.

Laravel utilizes the DotEnv PHP library. Sensitive configuration values (database credentials, API keys, etc.) should be stored in the .env file at the root of your project. This file should not be committed to version control.

A .env.example file is included with Laravel. You should copy it to .env and modify it:

cp .env.example .env

Key .env variables:

  • APP_NAME: Your application’s name.
  • APP_ENV: The current environment (e.g., local, production, testing).
  • APP_KEY: A unique, 32-character string for encryption. Generate with php artisan key:generate.
  • APP_DEBUG: Set to true in local development to see detailed errors, false in production.
  • APP_URL: The base URL of your application.
  • DB_CONNECTION, DB_HOST, DB_DATABASE, etc.: Database connection details.
  • MAIL_MAILER, MAIL_HOST, etc.: Mail configuration.

You can access configuration values using the config() helper function anywhere in your application:

$appName = config('app.name');
$databaseConnection = config('database.default');

To boost performance in production, cache your configuration files:

php artisan config:cache

To clear the cache: php artisan config:clear.

When your application is in maintenance mode, a custom view will be displayed for all requests. This is useful when updating your application or performing scheduled maintenance.

Start Maintenance Mode:

php artisan down

You can also provide options for redirection or a secret bypass:

php artisan down --redirect=/maintenance --retry=60 --secret="your-bypass-token"

Stop Maintenance Mode:

php artisan up

Customize the maintenance mode view by creating resources/views/errors/503.blade.php.

The most basic Laravel routes accept a URI and a Closure, providing a very simple and expressive method of defining routes. Routes are typically defined in routes/web.php for web interface routes and routes/api.php for API routes.

Available Router Methods:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Example (routes/web.php):

use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome'); // Returns the welcome Blade view
});
Route::get('/hello', function () {
return 'Hello World!';
});

Routing to Controllers:

use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);

Sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user’s ID from the URL.

Route::get('/user/{id}', function (string $id) {
return 'User ID: ' . $id;
});

You may also specify route parameters that are not always present in the URI path. You may do so by placing a ? mark after the parameter name and providing a default value for the variable.

Route::get('/user/{name?}', function (string $name = 'Guest') {
return 'Username: ' . $name;
});

Laravel automatically injects model instances directly into your routes or controllers if a route segment name matches a type-hinted variable name. For example, instead of injecting a user’s ID, you can inject the entire User model instance that matches the given ID.

use App\Models\User;
Route::get('/users/{user}', function (User $user) { // {user} matches $user
return $user->email;
});

Named routes allow you to conveniently generate URLs or redirects for specific routes.

Route::get('/user/profile', [UserProfileController::class, 'show'])->name('profile.show');
// Generating URL:
// $url = route('profile.show', ['id' => 1]);
// Redirecting:
// return redirect()->route('profile.show', ['id' => 1]);

Route groups allow you to share route attributes, such as middleware or prefixes, across a large number of routes without needing to define those attributes on each individual route.

Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
Route::get('/users', [AdminUserController::class, 'index'])->name('users.index');
});

Middleware provide a mechanism for filtering HTTP requests entering your application. They act as layers that requests pass through.

Create middleware using php artisan make:middleware <MiddlewareName>.

Register in app/Http/Kernel.php:

  • Global: $middleware array.
  • Groups: $middlewareGroups array (e.g., web, api).
  • Route Aliases: $middlewareAliases array.

Pass parameters from routes to middleware, e.g., middleware('role:editor'). The handle method receives these after $next.

Perform tasks after the response is sent using a terminate method in the middleware.

For detailed examples, refer to the Laravel Middleware section.

Controllers organize request handling logic into classes, typically stored in app/Http/Controllers.

php artisan make:controller <ControllerName>

php artisan make:controller PhotoController --resource generates a controller with CRUD methods. Use Route::resource('photos', PhotoController::class); to route.

php artisan make:controller ProvisionServer --invokable creates a controller with an __invoke method.

Laravel automatically injects dependencies (type-hinted in constructor or methods) via its service container.

For detailed examples, refer to the Laravel Controllers section.

Laravel’s Illuminate\Http\Request class provides an object-oriented way to interact with the current HTTP request, including retrieving input, cookies, and files.

You can type-hint Illuminate\Http\Request in your controller methods.

use Illuminate\Http\Request;
public function store(Request $request)
{
$path = $request->path(); // 'foo/bar'
$url = $request->url(); // 'http://example.com/foo/bar'
$fullUrl = $request->fullUrl(); // 'http://example.com/foo/bar?name=taylor'
$method = $request->method(); // 'GET', 'POST', etc.
$isPost = $request->isMethod('post');
// Check if path matches a pattern
if ($request->is('admin/*')) { /* ... */ }
}
$name = $request->input('name'); // From query string or form data
$email = $request->input('email', 'default@example.com'); // With default value
// Retrieve all input as an array
$allInput = $request->all();
// Retrieve only specific input
$subset = $request->only(['username', 'password']);
$except = $request->except(['credit_card']);
// Dynamic properties
$name = $request->name;
if ($request->hasFile('photo') && $request->file('photo')->isValid()) {
$file = $request->file('photo');
$path = $file->store('avatars', 'public'); // Store in storage/app/public/avatars
}

For a practical example of input retrieval in a form, see the Validation or File Uploading sections.

Laravel provides a simple API for managing HTTP cookies. All cookies are encrypted and signed by default.

Attach to a response: return response('Hello')->cookie('name', 'value', $minutes); Queue with facade: Cookie::queue('name', 'value', $minutes);

From request: $value = $request->cookie('name'); Using facade: $value = Cookie::get('name');

Attach expired: return response('Deleted')->withoutCookie('name'); Queue forgotten: Cookie::queue(Cookie::forget('name'));

For detailed examples, refer to the Laravel Cookie section.

All routes and controllers should return a response to be sent back to the user’s browser. Laravel provides several ways to return responses.

Strings and arrays are automatically converted to HTTP responses.

Route::get('/', function () { return 'Hello World'; });
Route::get('/array', function () { return [1, 2, 3]; }); // Becomes JSON

For more control, use the response() helper or Illuminate\Http\Response class.

return response('Custom content', 200)
->header('Content-Type', 'text/plain')
->header('X-Custom-Header', 'value');
return response()->json(['name' => 'Abigail', 'state' => 'CA']);
return response()->json(['error' => 'Not found'], 404);
return response()->download(storage_path('app/files/report.pdf'));
return response()->download(storage_path('app/files/report.pdf'), 'user-report.pdf', $headers);

View Responses and Redirections are covered in their respective sections.

Views contain the HTML served by your application and separate your controller/application logic from your presentation logic. Views are stored in the resources/views directory.

Create a file like resources/views/greeting.blade.php:

<!-- View stored in resources/views/greeting.blade.php -->
<html>
<body>
<h1>Hello, {{ $name }}</h1>
</body>
</html>
Route::get('/greet', function () {
return view('greeting', ['name' => 'James']);
});

Data can be passed as an array as the second argument to view(), or using the with() method.

return view('profile', ['user' => $user]);
// or
return view('profile')->with('user', $user)->with('posts', $posts);

Use View::share('key', 'value') in the boot method of a service provider (e.g., AppServiceProvider).

Blade is Laravel’s simple, yet powerful templating engine. Blade view files use the .blade.php extension.

Key Blade Directives:

  • {{ $variable }}: Display data (escaped by default).
  • {!! $variable !!}: Display unescaped data (use with caution).
  • @if, @elseif, @else, @endif: Conditional statements.
  • @foreach, @forelse, @while, @for: Loops.
  • @csrf: CSRF token field.
  • @method('PUT'): Method spoofing for forms.
  • @include('partials.header'): Include sub-views.
  • @extends('layouts.app'): Inherit a master layout.
  • @section('content') ... @endsection: Define content sections.
  • @yield('title'): Display content of a section from child view.
resources/views/layouts/app.blade.php
<html>
<head><title>@yield('title', 'My App')</title></head>
<body>
@include('partials.nav')
<div class="container">
@yield('content')
</div>
</body>
</html>
// resources/views/home.blade.php
@extends('layouts.app')
@section('title', 'Homepage')
@section('content')
<p>This is the home page content.</p>
@endsection

Redirect responses are instances of Illuminate\Http\RedirectResponse, and contain the proper headers needed to redirect the user to another URL.

return redirect('/home/dashboard');
return redirect()->route('profile.show', ['id' => 1]);
return redirect()->action([UserController::class, 'profile'], ['id' => 1]);
return back()->withInput(); // Redirects to previous location, with old input flashed to session
return redirect()->route('dashboard')->with('status', 'Profile updated!');
// In dashboard.blade.php:
// @if (session('status')) <div class="alert alert-success">{{ session('status') }}</div> @endif

Laravel supports MySQL, PostgreSQL, SQLite, and SQL Server. Configuration is in .env and config/database.php.

Use migrations for schema version control: php artisan make:migration create_users_table. Run with php artisan migrate.

Fluent interface for database queries: DB::table('users')->where('active', 1)->get();

ActiveRecord implementation: User::where('active', 1)->orderBy('name')->get();

For detailed examples and raw SQL, refer to the Laravel Working With Database section.

Error and exception handling is configured in App\Exceptions\Handler. APP_DEBUG=true in .env shows detailed errors in development.

Laravel uses the Monolog library. Configure logging channels in config/logging.php. Default log file is storage/logs/laravel.log. Use the Log facade:

use Illuminate\Support\Facades\Log;
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

Laravel does not include a built-in HTML form builder like older versions did with laravelcollective/html. Instead, you use standard HTML forms within your Blade templates.

<form method="POST" action="{{ route('routeName') }}">
@csrf {{-- CSRF protection --}}
<div>
<label for="email">Email Address</label>
<input type="email" id="email" name="email" value="{{ old('email') }}" required>
@error('email')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
@error('password')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
@if (false) {{-- Example for PUT/PATCH/DELETE requests --}}
@method('PUT') {{-- Or PATCH, DELETE --}}
@endif
<div>
<button type="submit">Submit</button>
</div>
</form>
  • @csrf: Generates a hidden input field containing the CSRF token.
  • method="POST": Standard for form submissions that modify data.
  • action="{{ route('routeName') }}": Use named routes for form actions.
  • {{ old('input_name') }}: Repopulates the form with old input if validation fails.
  • @error('input_name') ... @enderror: Displays validation errors for a specific field.
  • @method('VERB'): For PUT, PATCH, or DELETE requests, as HTML forms only support GET and POST.

For file uploads, add enctype="multipart/form-data" to the <form> tag. See the File Uploading section.

Laravel’s localization features provide a convenient way to retrieve strings in various languages, allowing you to easily support multiple languages within your application.

Language strings are stored in files within the lang directory (e.g., lang/en/messages.php, lang/es/messages.php). Or, for JSON based files: lang/en.json, lang/es.json.

PHP File Example (lang/en/messages.php):

<?php
return [
'welcome' => 'Welcome to our application!',
'greeting' => 'Hello, :name!',
];

Use the __ helper function or @lang Blade directive.

echo __('messages.welcome');
// In Blade: {{ __('messages.welcome') }} or @lang('messages.welcome')
echo __('messages.greeting', ['name' => 'Taylor']);

The application’s default locale is set in config/app.php (locale). You can change the active locale at runtime:

use Illuminate\Support\Facades\App;
App::setLocale('es'); // Sets current locale to Spanish

A common practice is to set the locale via a middleware based on a URL segment or user preference.

HTTP applications are stateless. Sessions provide a way to store information about the user across multiple requests. Laravel ships with a variety of session backends (file, cookie, database, Memcached/Redis, etc.) configurable in config/session.php and .env (SESSION_DRIVER).

Accessing Session Data (Illuminate\Http\Request):

Section titled “Accessing Session Data (Illuminate\Http\Request):”
// Store data
$request->session()->put('key', 'value');
// Retrieve data
$value = $request->session()->get('key', 'default');
// Check if data exists
if ($request->session()->has('users')) { /* ... */ }
// Retrieve all data
$allData = $request->session()->all();
// Remove an item
$request->session()->forget('key');
// Remove all items
$request->session()->flush();
session(['key' => 'value']); // Store
$value = session('key', 'default'); // Retrieve

Flash data is stored in the session for only the next request.

$request->session()->flash('status', 'Task was successful!');
// After redirect, in next request's view:
// @if (session('status')) {{ session('status') }} @endif

Laravel provides several different approaches to validate your application’s incoming data. The most common is using the validate method available on all incoming HTTP requests, or creating Form Request classes.

public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'publish_at' => 'nullable|date',
]);
// The validated data is available in $validated array
// If validation fails, a RedirectResponse is automatically generated
// or a JsonResponse with errors for AJAX requests.
}

The $errors variable is automatically made available to all views. It’s an instance of Illuminate\Support\MessageBag.

@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- For a specific field -->
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror

Laravel provides a vast number of validation rules, including required, email, unique, min, max, date, confirmed, image, in, alpha, etc. Refer to the official validation documentation for a complete list.

For more complex validation, create Form Request classes using php artisan make:request StorePostRequest. These classes contain their own authorization and validation logic.

HTML form must have enctype="multipart/form-data".

$request->validate(['avatar' => 'required|image|mimes:jpeg,png|max:2048']);
if ($request->hasFile('avatar')) {
$path = $request->file('avatar')->store('avatars', 'public');
// Run `php artisan storage:link` to make public disk accessible
}

For detailed examples, refer to the Laravel File Uploading section.

Laravel uses Symfony Mailer. Configure via .env and config/mail.php.

Create mailable classes: php artisan make:mail OrderShipped. Configure sender, recipient, subject, and view in the mailable class.

use Illuminate\Support\Facades\Mail;
use App\Mail\OrderShipped;
Mail::to($recipient)->send(new OrderShipped($order));

For detailed examples, refer to the Laravel Sending Email section.

Handle client-side asynchronous requests. Remember CSRF protection.

Add <meta name="csrf-token" content="{{ csrf_token() }}"> to Blade. Configure JS library (e.g., jQuery $.ajaxSetup or Axios) to send X-CSRF-TOKEN header.

Return response()->json(['data' => $data]); from controller.

For detailed examples, refer to the Laravel Ajax section.

All exceptions are handled by App\Exceptions\Handler class. It has report() (for logging) and render() (for HTTP response) methods.

Use abort(404); or abort(500, 'Something went wrong.'); to generate HTTP error responses.

Create Blade views in resources/views/errors/ (e.g., 404.blade.php, 503.blade.php) for custom error displays.

Laravel’s events provide a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application.

`php artisan make:event PodcastProcessed`
`php artisan make:listener SendPodcastNotification --event=PodcastProcessed`

Typically, listeners are automatically discovered if they are in the App\Listeners directory and correctly type-hint the event in their handle method. Manual registration is done in App\Providers\EventServiceProvider’s $listen array:

protected $listen = [
\App\Events\PodcastProcessed::class => [
\App\Listeners\SendPodcastNotification::class,
],
];
use App\Events\PodcastProcessed;
PodcastProcessed::dispatch($podcast); // Or event(new PodcastProcessed($podcast));

Listener handle method:

public function handle(PodcastProcessed $event): void
{
// Access $event->podcast and perform actions
}

Facades provide a “static” interface to classes available in the application’s service container. They offer a terse, expressive syntax while maintaining testability.

use Illuminate\Support\Facades\Cache;
Cache::put('key', 'value', $minutes);
$value = Cache::get('key');
  1. Create a class with the functionality.
  2. Create a Facade class extending Illuminate\Support\Facades\Facade, implementing getFacadeAccessor() to return the service container binding key.
  3. Bind your class in a service provider (e.g., App::bind('my-service', function() { return new MyService(); });).
  4. (Optional) Add an alias for the facade in config/app.php’s aliases array.

Laravel provides robust security features out of the box.

  • Password Hashing: Uses Hash facade (Bcrypt by default): Hash::make('password'), Hash::check('plain-text', $hashedPassword).
  • Authentication: Built-in services for user login, registration, password reset. See Auth facade.
  • Authorization (Gates & Policies): Fine-grained control over user permissions.
  • CSRF Protection: Automatic protection for POST, PUT, PATCH, DELETE routes in the web middleware group. Use @csrf in forms.
  • XSS Protection: Blade’s {{ }} syntax automatically escapes output. Use {!! !!} with extreme caution.
  • SQL Injection Protection: Eloquent ORM and Query Builder use PDO parameter binding, protecting against SQL injection by default.
  • Cookie Encryption & Signing: Cookies are automatically encrypted and signed.
  • HTTPS: Enforce HTTPS for sensitive data using middleware or URL::forceScheme('https') in a service provider.