Структура директорий Laravel
Общий обзор
Laravel 11 представил «тонкий» скелет приложения (slim skeleton), существенно упростив начальную структуру проекта. Многие файлы и директории создаются только по необходимости.
Корневая структура проекта
my-app/
├── app/ # Application code (Models, Controllers, etc.)
├── bootstrap/ # Framework bootstrap and cache files
│ ├── app.php # Application instance creation
│ ├── cache/ # Cached config, routes, services
│ └── providers.php # Service providers registration
├── config/ # Configuration files
├── database/ # Migrations, factories, seeders
│ ├── factories/ # Model factories for testing
│ ├── migrations/ # Database migration files
│ └── seeders/ # Database seed classes
├── public/ # Web server document root
│ ├── index.php # Application entry point
│ ├── .htaccess # Apache rewrite rules
│ └── favicon.ico
├── resources/ # Views, raw assets, language files
│ ├── css/ # CSS source files
│ ├── js/ # JavaScript source files
│ └── views/ # Blade templates
├── routes/ # Route definitions
│ ├── web.php # Web routes (session, CSRF)
│ └── console.php # Console commands (closures)
├── storage/ # Compiled views, logs, file uploads
│ ├── app/ # Application files
│ │ └── public/ # Public files (symlinked)
│ ├── framework/ # Framework-generated files
│ │ ├── cache/ # File-based cache
│ │ ├── sessions/ # File-based sessions
│ │ └── views/ # Compiled Blade views
│ └── logs/ # Application logs
├── tests/ # Automated tests
│ ├── Feature/ # Feature (integration) tests
│ └── Unit/ # Unit tests
├── vendor/ # Composer dependencies (not in Git)
├── .env # Environment variables (not in Git)
├── .env.example # Environment template
├── artisan # CLI entry point
├── composer.json # PHP dependencies
├── package.json # Node.js dependencies
├── phpunit.xml # PHPUnit configuration
└── vite.config.js # Vite asset bundler config
Ключевое изменение Laravel 11: Из скелета удалены файлы
app/Http/Kernel.php,app/Console/Kernel.php,app/Exceptions/Handler.phpи большинство сервис-провайдеров. Их функциональность перенесена вbootstrap/app.php.
Директория app/
Директория app/ содержит основной код приложения. Использует пространство имён App\ с автозагрузкой PSR-4.
Структура app/ в Laravel 11
app/
├── Console/ # (Created on demand)
│ └── Commands/ # Custom Artisan commands
├── Exceptions/ # (Created on demand)
├── Http/
│ ├── Controllers/ # Request handlers
│ │ └── Controller.php # Base controller (slim)
│ ├── Middleware/ # (Created on demand)
│ └── Requests/ # (Created on demand)
├── Models/ # Eloquent models
│ └── User.php # Default User model
└── Providers/
└── AppServiceProvider.php # Main service provider
Для экзамена: В Laravel 11 по умолчанию только ОДИН сервис-провайдер --
AppServiceProvider. Ранее было 5: AppServiceProvider, AuthServiceProvider, BroadcastServiceProvider, EventServiceProvider, RouteServiceProvider.
Дополнительные директории app/ (создаются по необходимости)
# Created automatically by artisan make: commands
app/
├── Casts/ # php artisan make:cast
├── Console/Commands/ # php artisan make:command
├── Events/ # php artisan make:event
├── Exceptions/ # php artisan make:exception
├── Http/Middleware/ # php artisan make:middleware
├── Http/Requests/ # php artisan make:request
├── Http/Resources/ # php artisan make:resource
├── Jobs/ # php artisan make:job
├── Listeners/ # php artisan make:listener
├── Mail/ # php artisan make:mail
├── Notifications/ # php artisan make:notification
├── Observers/ # php artisan make:observer
├── Policies/ # php artisan make:policy
├── Rules/ # php artisan make:rule
├── Services/ # Created manually (no artisan command)
├── Actions/ # Created manually (single-action classes)
├── DTOs/ # Created manually (Data Transfer Objects)
├── Enums/ # Created manually (PHP 8.1+ enums)
└── ValueObjects/ # Created manually
<?php
declare(strict_types=1);
// Naming convention: singular for most directories
// app/Models/User.php → App\Models\User
// app/Http/Controllers/UserController.php → App\Http\Controllers\UserController
// app/Services/PaymentService.php → App\Services\PaymentService
// PSR-4 autoloading maps namespace to directory:
// "App\\" → "app/"
// App\Models\User → app/Models/User.php
// App\Http\Controllers\Api\V1\UserController → app/Http/Controllers/Api/V1/UserController.php
Директория bootstrap/
bootstrap/
├── app.php # Application instance and configuration
├── cache/ # Framework cache files
│ ├── config.php # Cached configuration (after config:cache)
│ ├── events.php # Cached event-listener mapping
│ ├── packages.php # Auto-discovered package service providers
│ ├── routes-v7.php # Cached routes (after route:cache)
│ └── services.php # Compiled service container
└── providers.php # Service providers list
bootstrap/app.php в Laravel 11
<?php
declare(strict_types=1);
// bootstrap/app.php — the new central configuration point
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
api: __DIR__ . '/../routes/api.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// Configure global middleware
$middleware->web(append: [
\App\Http\Middleware\HandleInertiaRequests::class,
]);
// API middleware
$middleware->api(prepend: [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
]);
// Middleware aliases
$middleware->alias([
'role' => \App\Http\Middleware\CheckRole::class,
'admin' => \App\Http\Middleware\EnsureIsAdmin::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
// Configure exception handling
$exceptions->renderable(function (\Throwable $e) {
// Custom exception rendering
});
})
->create();
Важно для Senior: В Laravel 11 файл
bootstrap/app.phpзаменяетHttp/Kernel.php,Console/Kernel.phpиExceptions/Handler.php. Это единая точка конфигурации маршрутов, middleware и обработки исключений.
bootstrap/providers.php
<?php
declare(strict_types=1);
// bootstrap/providers.php — list of service providers
return [
App\Providers\AppServiceProvider::class,
// Add custom providers here
// App\Providers\EventServiceProvider::class,
// App\Providers\AuthServiceProvider::class,
];
Директория config/
<?php
declare(strict_types=1);
// config/app.php — main application config
// config/auth.php — authentication guards and providers
// config/cache.php — cache store drivers
// config/database.php — database connections
// config/filesystems.php — filesystem disks
// config/logging.php — log channels
// config/mail.php — mail drivers
// config/queue.php — queue connections
// config/services.php — third-party services
// config/session.php — session configuration
// Custom config files are automatically loaded
// config/payment.php → config('payment.key')
// config/social.php → config('social.facebook.app_id')
// Laravel 11: Many config files removed from skeleton
// Publish with: php artisan config:publish <name>
Директория database/
database/
├── factories/
│ └── UserFactory.php # Model factory for User
├── migrations/
│ ├── 0001_01_01_000000_create_users_table.php
│ ├── 0001_01_01_000001_create_cache_table.php
│ └── 0001_01_01_000002_create_jobs_table.php
└── seeders/
└── DatabaseSeeder.php # Main seeder
<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
/**
* @extends Factory<User>
*/
final class UserFactory extends Factory
{
// Factory automatically maps to model by convention:
// UserFactory → App\Models\User
// OrderFactory → App\Models\Order
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => Hash::make('password'),
'remember_token' => Str::random(10),
];
}
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
<?php
declare(strict_types=1);
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
final class DatabaseSeeder extends Seeder
{
public function run(): void
{
// Create a test user
User::factory()->create([
'name' => 'Test User',
'email' => '[email protected]',
]);
// Create multiple users
User::factory(50)->create();
// Call other seeders
$this->call([
// CategorySeeder::class,
// ProductSeeder::class,
]);
}
}
Директория public/
public/
├── index.php # Application entry point
├── .htaccess # Apache URL rewriting
├── favicon.ico
├── robots.txt
└── build/ # Compiled assets (Vite output, gitignored)
<?php
declare(strict_types=1);
// public/index.php — the entry point for ALL HTTP requests
// This is a simplified view of what happens:
// 1. Define start time for performance measurement
define('LARAVEL_START', microtime(true));
// 2. Maintenance mode check
if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) {
require $maintenance;
}
// 3. Register Composer autoloader
require __DIR__ . '/../vendor/autoload.php';
// 4. Bootstrap the application and handle the request
/** @var \Illuminate\Foundation\Application $app */
$app = require_once __DIR__ . '/../bootstrap/app.php';
// 5. Handle incoming request and send response
$app->handleRequest(
\Illuminate\Http\Request::capture()
);
Для экзамена: Файл
public/index.php-- это единственная точка входа для всех HTTP-запросов (front controller pattern). Веб-сервер (Nginx/Apache) должен указывать document root на директориюpublic/, а не на корень проекта. Это защищает конфигурационные файлы и исходный код от прямого доступа.
Директория resources/
resources/
├── css/
│ └── app.css # Main CSS file (Tailwind, etc.)
├── js/
│ ├── app.js # Main JavaScript entry
│ └── bootstrap.js # Axios, Echo setup
└── views/
├── welcome.blade.php # Default welcome page
└── layouts/ # Layout templates (created manually)
<?php
declare(strict_types=1);
// Views are organized by convention:
// resources/views/users/index.blade.php → view('users.index')
// resources/views/admin/users/edit.blade.php → view('admin.users.edit')
// resources/views/components/alert.blade.php → <x-alert />
// Language files (if using JSON translation)
// resources/lang/en.json
// resources/lang/ru.json
// Language files (if using PHP translation)
// resources/lang/en/messages.php
// resources/lang/ru/messages.php
// In Laravel 11, lang directory is NOT created by default
// Publish with: php artisan lang:publish
Директория routes/
Laravel 11: Упрощённая маршрутизация
routes/
├── web.php # Web routes (session, CSRF, cookies)
├── console.php # Artisan command definitions
└── api.php # API routes (created on demand)
Важно: В Laravel 11 файл
routes/api.phpНЕ создаётся по умолчанию. Для его создания выполнитеphp artisan install:api, что также установит Laravel Sanctum.
<?php
declare(strict_types=1);
// routes/web.php — routes with web middleware group
// Includes: session, CSRF protection, cookie encryption
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
// routes/console.php — closure-based artisan commands
use Illuminate\Support\Facades\Schedule;
Schedule::command('inspire')->hourly();
// routes/api.php — routes with api middleware group
// Created after: php artisan install:api
// Includes: Sanctum, rate limiting, stateless
// routes/channels.php — broadcast channel authorization
// Created after: php artisan install:broadcasting
<?php
declare(strict_types=1);
// Laravel 11: Route files are loaded in bootstrap/app.php
// No more RouteServiceProvider
// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
api: __DIR__ . '/../routes/api.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up', // Health check endpoint
// Custom route loading
then: function () {
Route::middleware('web')
->prefix('admin')
->group(base_path('routes/admin.php'));
},
)
->create();
Директория storage/
storage/
├── app/ # Application files
│ ├── public/ # Publicly accessible files (symlinked)
│ └── private/ # Private files
├── framework/ # Framework-generated files
│ ├── cache/ # File cache (if file driver)
│ │ └── data/
│ ├── sessions/ # File sessions (if file driver)
│ ├── testing/ # Test files
│ └── views/ # Compiled Blade templates
└── logs/ # Application log files
└── laravel.log # Default log file
# Create symbolic link: public/storage → storage/app/public
php artisan storage:link
# This allows public access to files in storage/app/public
# URL: /storage/filename.jpg → storage/app/public/filename.jpg
<?php
declare(strict_types=1);
use Illuminate\Support\Facades\Storage;
// Using Storage facade
Storage::disk('local')->put('file.txt', 'Content'); // storage/app/file.txt
Storage::disk('public')->put('photo.jpg', $imageData); // storage/app/public/photo.jpg
Storage::disk('s3')->put('backup.zip', $data); // AWS S3
// Path helpers
$path = storage_path(); // /path/to/storage
$path = storage_path('app/file.txt'); // /path/to/storage/app/file.txt
$path = storage_path('logs/laravel.log'); // /path/to/storage/logs/laravel.log
Для Senior: Директория
storage/должна быть записываемой веб-сервером. Права доступа:chmod -R 775 storage. В Docker-контейнерах убедитесь, что пользователь контейнера имеет права на запись. Логи ротации настраиваются вconfig/logging.php.
Директория tests/
tests/
├── Feature/ # Integration/Feature tests
│ └── ExampleTest.php
├── Unit/ # Unit tests
│ └── ExampleTest.php
├── Pest.php # Pest configuration (if using Pest)
└── TestCase.php # Base test case
<?php
declare(strict_types=1);
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
// Base test case — all tests extend this
// Provides: RefreshDatabase, WithFaker, etc.
}
Вспомогательные функции путей
<?php
declare(strict_types=1);
// Path helper functions
$path = app_path(); // /project/app
$path = app_path('Models/User.php'); // /project/app/Models/User.php
$path = base_path(); // /project
$path = base_path('vendor/autoload.php');// /project/vendor/autoload.php
$path = config_path(); // /project/config
$path = config_path('app.php'); // /project/config/app.php
$path = database_path(); // /project/database
$path = database_path('migrations'); // /project/database/migrations
$path = public_path(); // /project/public
$path = public_path('css/app.css'); // /project/public/css/app.css
$path = resource_path(); // /project/resources
$path = resource_path('views'); // /project/resources/views
$path = storage_path(); // /project/storage
$path = storage_path('logs'); // /project/storage/logs
$path = lang_path(); // /project/lang
$path = lang_path('en/messages.php'); // /project/lang/en/messages.php
Различия Laravel 10 vs Laravel 11
| Аспект | Laravel 10 | Laravel 11 |
|---|---|---|
| Http Kernel | app/Http/Kernel.php |
bootstrap/app.php |
| Console Kernel | app/Console/Kernel.php |
bootstrap/app.php |
| Exception Handler | app/Exceptions/Handler.php |
bootstrap/app.php |
| Service Providers | 5 по умолчанию | 1 (AppServiceProvider) |
| Middleware | 9 файлов в app/Http/Middleware/ |
0 файлов (по требованию) |
| routes/api.php | Существует по умолчанию | php artisan install:api |
| routes/channels.php | Существует по умолчанию | php artisan install:broadcasting |
| Config файлы | ~15 файлов | ~10 файлов |
| Минимум PHP | 8.1 | 8.2 |