Разработка веб-приложений на Laravel PHP: практические примеры и решения
Основной подход: создание базового приложения Laravel с нуля
Как установить Laravel и запустить первое приложение?
Установка Laravel выполняется через Composer. Для начала требуется PHP версии 8.1 или выше, а также Composer. Выполнение команды composer create-project laravel/laravel myapp создаст новый проект. После перехода в директорию cd myapp запускается встроенный сервер командой php artisan serve. Приложение становится доступно по адресу http://localhost:8000.
composer create-project laravel/laravel blog
cd blog
php artisan serveLaravel app php (приложение laravel php)
Проблема: Ошибка "Composer не найден" или "PHP версия ниже 8.1".
Решение: Установка актуальной версии PHP через менеджер пакетов (например, apt install php8.2 на Ubuntu) и проверка Composer командой composer --version.
Как настроить подключение к базе данных?
В файле .env указываются параметры подключения: DB_CONNECTION=mysql, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD. Для SQLite достаточно установить DB_CONNECTION=sqlite и создать пустой файл database/database.sqlite. После настройки создаются миграции командой php artisan migrate.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=root
DB_PASSWORD=secretКак создать модель, миграцию и контроллер для сущности Post?
Одной командой Artisan создаются все компоненты: php artisan make:model Post -mc. Эта команда генерирует модель Post, миграцию для таблицы posts и контроллер PostController. В миграции добавляются поля: title, content, user_id. После редактирования файла миграции выполняется php artisan migrate.
php artisan make:model Post -mc// database/migrations/xxxx_create_posts_table.php
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->foreignId('user_id')->constrained();
$table->timestamps();
});Ошибка: "Class 'Post' not found" при использовании модели без импорта.
Решение: Добавить use App\Models\Post; в начале файла контроллера.
Как реализовать CRUD для постов?
В контроллере PostController создаются методы: index (список), create (форма), store (сохранение), show (просмотр), edit (редактирование), update (обновление), destroy (удаление). Для примера метод store:
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|max:255',
'content' => 'required',
]);
$post = Post::create([
'title' => $validated['title'],
'content' => $validated['content'],
'user_id' => auth()->id(),
]);
return redirect()->route('posts.show', $post);
}Маршруты для ресурса регистрируются одной строкой: Route::resource('posts', PostController::class);. Шаблоны Blade создаются в папке resources/views/posts.
Проблема: Ошибка валидации "The title field is required" не отображается в представлении.
Решение: В шаблоне добавить вывод ошибок: @if($errors->any()) ... @endif и @error('title').
Вариант 1: Использование Laravel Breeze для аутентификации
Как быстро добавить регистрацию и вход в приложение?
Laravel Breeze предоставляет готовые шаблоны и контроллеры. Установка: composer require laravel/breeze --dev, затем php artisan breeze:install и npm install && npm run dev. После этого доступны маршруты login, register, dashboard. Вариант подходит для простых проектов с минимальной аутентификацией.
composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrateПроблема: После breeze:install страница dashboard возвращает ошибку 404.
Решение: Запустить php artisan route:list и убедиться, что маршруты зарегистрированы. Возможно, требуется перезапустить сервер.
Вариант 2: Создание API с аутентификацией через Laravel Sanctum
Как разработать REST API для мобильного приложения?
Установка Sanctum: composer require laravel/sanctum, публикация конфигурации и миграции. Затем в модели User добавляется трейт HasApiTokens. Аутентификация по токенам. Пример создания токена:
$user = User::find(1);
$token = $user->createToken('api-token')->plainTextToken;
return response()->json(['token' => $token]);Защита маршрутов: Route::middleware('auth:sanctum')->group(...). Вариант подходит для одностраничных приложений (SPA) и мобильных клиентов.
Проблема: Токен не работает, ответ 401 Unauthenticated.
Решение: Проверить заголовок Authorization: Bearer {token} в запросе. Для SPA также настроить CORS в файле config/cors.php.
Вариант 3: Использование Livewire для динамического интерфейса без JavaScript
Как создать реактивный интерфейс с минимумом кода на клиенте?
Livewire позволяет создавать компоненты с серверной логикой. Установка: composer require livewire/livewire. Создание компонента: php artisan make:livewire PostForm. В классе определяются свойства и методы, а в шаблоне используется директива wire:model. Пример компонента для создания поста:
// app/Http/Livewire/PostForm.php
class PostForm extends Component
{
public $title, $content;
public function save()
{
$this->validate([
'title' => 'required',
'content' => 'required',
]);
Post::create([
'title' => $this->title,
'content' => $this->content,
'user_id' => auth()->id(),
]);
session()->flash('message', 'Пост создан.');
}
public function render()
{
return view('livewire.post-form');
}
}<div>
<input wire:model="title" placeholder="Заголовок">
<textarea wire:model="content"></textarea>
<button wire:click="save">Сохранить</button>
</div>Проблема: Livewire компонент не обновляется после сохранения.
Решение: Использовать $this->reset(['title', 'content']) или обновлять список постов через событие.
Расширенные примеры и нестандартные сценарии
Кастомное middleware для логирования запросов?
Создание middleware командой php artisan make:middleware LogRequests. В методе handle записывается информация в лог. Пример:
public function handle(Request $request, Closure $next)
{
Log::info('Request URL: ' . $request->fullUrl());
return $next($request);
}Регистрация в bootstrap/app.php (Laravel 11) или app/Http/Kernel.php. Результат: в файле storage/logs/laravel.log появляются записи.
[2025-03-25 10:15:30] local.INFO: Request URL: http://localhost:8000/posts
Использование сервис-провайдера для регистрации пользовательского фасада?
Создание фасада для работы с внешним API. Пример: фасад Weather. Сначала создается класс WeatherService, затем фасад WeatherFacade и сервис-провайдер WeatherServiceProvider. Регистрация в config/app.php. После этого вызов Weather::getTemperature('Moscow') возвращает данные.
// app/Services/WeatherService.php
class WeatherService
{
public function getTemperature(string $city): ?float
{
$apiKey = config('services.weather.key');
$response = Http::get("https://api.weatherapi.com/v1/current.json", [
'key' => $apiKey,
'q' => $city,
]);
return $response->json('current.temp_c');
}
}
// app/Facades/Weather.php
class Weather extends Facade
{
protected static function getFacadeAccessor()
{
return 'weather';
}
}
// app/Providers/WeatherServiceProvider.php
public function register(): void
{
$this->app->bind('weather', function ($app) {
return new WeatherService();
});
}Результат вызова: 5.3 (температура в Цельсиях)
Настройка очередей для отправки писем?
Установка драйвера очереди (например, database): выполнение php artisan queue:table и миграция. В контроллере отправка письма ставится в очередь:
use App\Mail\WelcomeMail;
use Illuminate\Support\Facades\Mail;
public function register(Request $request)
{
$user = User::create(...);
Mail::to($user->email)->queue(new WelcomeMail($user));
return redirect()->back();
}Запуск обработчика очереди: php artisan queue:work. Результат: письма отправляются асинхронно, не блокируя ответ пользователю.
Проблема: Письма не отправляются, очередь не обрабатывается.
Решение: Убедиться, что worker запущен, и проверить таблицу jobs на наличие записей. Для production используется supervisor для управления worker.
Реализация событий и слушателей для уведомлений при создании поста?
Создание события php artisan make:event PostCreated и слушателя php artisan make:listener SendNewPostNotification --event=PostCreated. В слушателе отправка email всем подписчикам.
// app/Events/PostCreated.php
class PostCreated
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
}
// app/Listeners/SendNewPostNotification.php
public function handle(PostCreated $event): void
{
$subscribers = User::where('subscribed', true)->get();
foreach ($subscribers as $user) {
Mail::to($user->email)->send(new NewPostMail($event->post));
}
}Регистрация в EventServiceProvider. При вызове event(new PostCreated($post)) в контроллере срабатывает слушатель.
Тестирование HTTP-маршрутов с помощью PHPUnit?
Создание теста: php artisan make:test PostTest. Пример тестирования маршрута создания поста:
public function test_post_can_be_created(): void
{
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->post('/posts', [
'title' => 'Новый пост',
'content' => 'Содержание',
]);
$response->assertStatus(302); // redirect
$this->assertDatabaseHas('posts', [
'title' => 'Новый пост',
]);
}Запуск тестов: php artisan test. Результат: зеленые галочки при успешном прохождении.
PASS Tests\Feature\PostTest ✓ post can be created