Laravel Introduction
What Laravel is, installing it with Composer, php artisan serve, and the directory structure.
What is Laravel?
Laravel is an open-source PHP web framework created by Taylor Otwell in 2011, built around the MVC (Model-View-Controller) pattern and widely regarded as the most popular framework in the PHP ecosystem. Its defining trait is expressiveness — Laravel favors clean, readable syntax over verbose configuration, and it ships with first-party solutions for almost everything a web application needs: routing, an ORM (Eloquent), templating (Blade), authentication, queues, caching, testing, and more, all designed to work together coherently.
That combination — elegant syntax plus a huge, well-maintained ecosystem (Forge, Vapor, Nova, Sanctum, Cashier, and hundreds of first-party and community packages) — is why Laravel is often described as bringing Ruby on Rails–style developer happiness to PHP.
Installing Laravel
Laravel is installed via Composer, PHP's dependency manager:
composer create-project laravel/laravel example-app
cd example-app
This downloads Laravel and every framework dependency into a fresh project. Once installed, generate the APP_KEY (used to encrypt sessions and cookies) if it isn't already set:
php artisan key:generate
Running the development server
php artisan serve
By default this starts a local server at http://127.0.0.1:8000. Like Flask's, FastAPI's, and Django's built-in dev servers, artisan serve is meant purely for local development — a real deployment runs behind Nginx or Apache with PHP-FPM, or a managed platform like Laravel Forge or Vapor.
The directory structure at a glance
A fresh Laravel project has a predictable, consistent layout:
example-app/
app/
Http/
Controllers/
Middleware/
Models/
Providers/
bootstrap/
app.php
config/
database/
migrations/
factories/
seeders/
resources/
views/
css/
js/
routes/
web.php
console.php
tests/
artisan
composer.json
.env
| Directory | Purpose |
|---|---|
app/Models |
Eloquent model classes |
app/Http/Controllers |
Controller classes |
app/Http/Middleware |
Custom middleware classes |
routes/web.php |
Routes for the browser-facing app (session, CSRF protection) |
resources/views |
Blade templates |
database/migrations |
Version-controlled schema changes |
config/ |
Application configuration files |
.env |
Environment-specific configuration (database credentials, API keys) — never committed to version control |
bootstrap/app.php |
Bootstraps the application, including middleware and routing configuration |
.env holds machine- and environment-specific values (database credentials, mail settings, third-party API keys) which config/*.php files read via env(). Committing real .env values to version control is a serious security mistake — only .env.example, a template with placeholder values, belongs in the repository.
Common mistakes
- Committing
.envto version control — it typically holds real database credentials and API keys and should always be excluded via.gitignore. - Running
php artisan servein production — it's a lightweight development server, not hardened or tuned for real traffic. - Editing files generated by Composer or by Artisan's scaffolding (like files under
vendor/) directly instead of through the intended extension points —vendor/is regenerated by Composer and any hand edits there are silently lost.
Interview questions
Q: What does composer create-project laravel/laravel actually do?
It uses Composer, PHP's dependency manager, to download the Laravel framework and every package it depends on into a new project directory, following the versions and structure defined by Laravel's own project skeleton. The result is a fully working, empty Laravel application — routes, Eloquent, Blade, and the rest already wired together — ready to build on immediately.
Q: Why does Laravel keep configuration in .env separate from the files in config/?
.env holds values that differ between environments (local, staging, production) or are sensitive (database passwords, API keys), while config/*.php files hold the actual configuration structure and read those environment-specific values through the env() helper. This separation means the same codebase can run correctly across every environment purely by swapping .env, without ever changing (or exposing) a single line of committed code.