<div><img src="https://top-fwz1.mail.ru/counter?id=3548135;js=na" style="position:absolute;left:-9999px;" alt="Top.Mail.Ru" /></div>
Публичное облако на базе VMware с управлением через vCloud Director

Как разработать админку на Laravel

Олег Мещеряков
Олег Мещеряков
Технический писатель
31 января 2025 г.
141
29 минут чтения
Средний рейтинг статьи: 3.3

В этом руководстве покажем, как разработать админку для небольшого проекта, используя встроенные инструменты Laravel. Этот процесс позволяет лучше понять структуру фреймворка, улучшить навыки работы с Laravel и почувствовать контроль над каждой частью приложения. 

Плюсы разработки своей админки:

  1. Глубокое понимание фреймворка: Создавая админку с нуля, вы изучаете работу Laravel изнутри, что помогает лучше понимать, как устроены маршруты, middleware, контроллеры и модели.

  2. Полный контроль над функциональностью: Сами решаете, какие функции необходимы в админке, и избегаете лишнего кода, который может быть в сторонних пакетах.

  3. Гибкость: Можете реализовать любую бизнес-логику, адаптированную под конкретные требования вашего проекта, без необходимости подстраиваться под ограничения готовых решений.

  4. Минимальная зависимость от сторонних библиотек: Снижается вероятность конфликтов версий и уязвимостей, которые могут быть в сторонних пакетах.

Минусы разработки своей админки:

  1. Больше времени на разработку: Самостоятельная реализация функциональности (например, CRUD для сущностей) требует больше времени, чем использование готовых решений.

  2. Меньше готовых инструментов: Сторонние пакеты часто предоставляют полезные функции «из коробки» (фильтры, сортировка, интерфейсы), которые нужно реализовывать вручную.

  3. Ограниченный функционал в упрощенном подходе: Избегая ООП и сложных решений, можно упустить важные аспекты, такие как масштабируемость и модульность.

Что вам понадобится знать:

  • Базовые знания языка программирования PHP
  • Умение использовать Composer для управления зависимостями
  • Умение настроить и подготовить окружение для локальной разработки

Окружение:

В этом руководстве используется следующее окружение:

  • Операционная система: Ubuntu 22.04.4 LTS
  • PHP: 8.3.15
  • Laravel: 9.x
  • Composer: 2.7.8
  • npm: 10.8.2
  • Node: 18.20.5
cloud

Подготовка окружения

Создание пользователя

Создайте пользователя lara и добавьте его в группы sudo и www-data:

adduser lara
usermod -aG sudo lara
usermod -aG www-data lara
su - lara

Установка PHP 8.3 и расширений для Laravel

Добавьте PPA для PHP:

sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

Установите PHP и расширения:

sudo apt install php8.3 php8.3-cli php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-bcmath php8.3-xml php8.3-zip php8.3-intl php8.3-soap php8.3-redis -y

Установка Composer

Обновите список пакетов:

sudo apt update

Скачайте установочный скрипт:

cd /usr/local/bin
sudo curl -sS https://getcomposer.org/installer -o composer-setup.php

Проверьте целостность файла:

HASH=$(curl -sS https://composer.github.io/installer.sig)
php -r "if (hash_file('sha384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

Установите Composer:

sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
sudo composer self-update 2.7.8

Проверьте установку:

composer --version

Установка Node.js и npm

Удалите старые версии:

sudo apt purge nodejs -y
sudo apt autoremove -y
sudo apt update

Установите Node.js 18.x:

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

Проверьте версии:

node -v
npm -v

Создание рабочей директории

Создайте папку для проекта:

cd /var
sudo mkdir www
sudo chown lara:www-data www
sudo chmod 775 www
cd www

Установка и настройка Nginx

Установите Nginx:

sudo apt install -y nginx
sudo ufw allow 'Nginx Full'

Настройте виртуальный хост:

sudo nano /etc/nginx/sites-available/lara.com

Вставьте:

server {
    listen 80;
    server_name <Публичный_IP-Адрес_Сервера или домен>;
    root /var/www/laravel-admin/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Активируйте конфигурацию:

sudo ln -s /etc/nginx/sites-available/lara.com /etc/nginx/sites-enabled/
sudo unlink /etc/nginx/sites-enabled/default

Перезапустите службы:

sudo systemctl restart nginx
sudo systemctl restart php8.3-fpm

Установка Laravel

Создайте проект:

composer create-project laravel/laravel:^9.0 laravel-admin

Настройте права на папки и файлы:

sudo find /var/www/laravel-admin -type f -exec chmod 644 {} \;
sudo find /var/www/laravel-admin -type d -exec chmod 755 {} \;
cd laravel-admin/
sudo chown -R lara:www-data .
sudo find . -type f -exec chmod 664 {} \;
sudo find . -type d -exec chmod 775 {} \;
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache

Установка и настройка SQLite

Установите расширение SQLite:

sudo apt install php8.3-sqlite3

Настройте подключение. В файле .env измените строки:

DB_CONNECTION=sqlite
DB_DATABASE=/var/www/laravel-admin/database/database.sqlite

Создайте базу данных:

touch database/database.sqlite

Измените владельца и группу для файла database.sqlite:

sudo chown lara:www-data /var/www/laravel-admin/database/database.sqlite

Запустите миграции:

php artisan migrate

Команду php artisan нужно выполнять из корня проекта: /var/www/laravel-admin.

Настройка провайдера

Провайдеры — это важная часть Laravel, представляющая собой специальные классы для настройки и инициализации компонентов приложения. Они позволяют определить, как должны быть организованы и связаны различные элементы системы. Laravel автоматически загружает провайдеры, указанные в файле config/app.php, что обеспечивает гибкость и модульность в управлении приложением.

Что делает RouteServiceProvider?

RouteServiceProvider — это системный провайдер, который отвечает за маршрутизацию в приложении. Его задачи включают:

  • Загрузку файлов маршрутов для веб-приложения, API и других частей системы.
  • Привязку моделей к маршрутам.
  • Настройку пространств имен (namespaces) для контроллеров.

Этот провайдер помогает организовать маршруты, разделяя их на группы (например, для административной панели и пользовательской части), а также задавать общие правила для маршрутов, такие как middleware, префиксы или ограничения.

Настройка RouteServiceProvider

Файл RouteServiceProvider.php находится в папке app/Providers. Поменяем значение константы HOME и отредактируем метод boot:

class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/dashboard';

public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::middleware('api')
                ->prefix('api')
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->group(base_path('routes/web.php'));

            Route::middleware(['web', 'auth'])
                ->namespace('App\Http\Controllers\Dashboard')
                ->prefix('dashboard')
                ->group(base_path('routes/dashboard.php'));

        });
    }

     // Остальной код провайдера
}

Основные изменения и настройки

Свойство HOME:

Определяет маршрут перенаправления для авторизованных пользователей после успешной аутентификации. В данном случае пользователи будут направлены на /dashboard. Это удобно для централизованного управления перенаправлением: если маршрут изменится, достаточно будет обновить только значение константы.

public const HOME = '/dashboard';

Метод boot:

В методе boot выполняется основная настройка маршрутов. Здесь используется метод routes, который позволяет описать правила маршрутизации для различных частей приложения.

Маршруты для веб-приложения:

Route::middleware('web')
->group(base_path('routes/web.php'));

Маршруты клиентской части подключаются из файла routes/web.php. Они используют только middleware web, что обеспечивает поддержку сессий, CSRF и других веб-функций.

Маршруты административной панели:

Route::middleware(['web', 'auth'])
->namespace('App\Http\Controllers\Dashboard')
     	->prefix('dashboard')
     	->group(base_path('routes/dashboard.php'));

Для маршрутов административной панели добавлено:

  • Middleware web и auth, ограничивающие доступ только для авторизованных пользователей.
  • Пространство имен App\Http\Controllers\Dashboard.
  • Префикс маршрутов dashboard, что делает их доступными по URL /dashboard/....
  • Расположение файла с маршрутами routes/dashboard.php.

Почему это важно?

Эта структура делает приложение модульным и удобным для масштабирования:

  • Разделение маршрутов по файлам упрощает управление ими.
  • Пространства имен позволяют использовать разные контроллеры для разных частей приложения.
  • Добавление middleware и префиксов на уровне группы маршрутов повышает безопасность и упрощает конфигурацию.

Обновление маршрутов

Создайте файл routes/dashboard.php и добавьте следующий маршрут:

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('dashboard.app');
})->name('dashboard.home');

Описание маршрута:

  1. Route::get('/'): Этот маршрут отвечает на GET-запросы по адресу /dashboard (так как в RouteServiceProvider для административной панели установлен префикс dashboard).

  2. Функция обратного вызова (callback): В функции обратного вызова возвращается вид (view) dashboard.app. Это базовый шаблон административной панели, который был создан ранее и наследует структуру из master.blade.php.

  3. Именование маршрута: ->name('dashboard.home'). Именование маршрута позволяет обращаться к нему по имени dashboard.home в шаблонах, контроллерах или при создании ссылок. Например, в Blade-шаблонах: <a href="{{ route('dashboard.home') }}">Главная</a>.

Назначение маршрута:

  • Это главная страница административной панели.

  • Этот маршрут используется для рендеринга базового шаблона административной панели, который можно настроить и наполнить необходимым содержимым.

Установка laravel/ui

Для использования стандартных фронтенд-стилей и аутентификации в Laravel, необходимо установить пакет laravel/ui. Этот пакет предоставляет базовые компоненты, такие как аутентификация, страницы входа и регистрации, а также позволяет использовать фронтенд-фреймворки, такие как Bootstrap или Vue.js.

Установка пакета laravel/ui

Установите пакет laravel/ui через Composer:

composer require laravel/ui

После установки пакета, выполните команду для генерации фронтенд-скелета с использованием Bootstrap:

php artisan ui bootstrap

Команду нужно выполнять из корня проекта: /var/www/laravel-admin.

Это создаст необходимые файлы для интеграции Bootstrap в проект, включая шаблоны и стили.

Настройка аутентификации

После того, как вы установили и настроили laravel/ui, вы можете сгенерировать стандартные страницы аутентификации (входа и регистрации). Для этого выполните команду:

php artisan ui bootstrap --auth

Согласитесь пересоздать файл Controller.php.

Эта команда создаст необходимые контроллеры, маршруты и представления для аутентификации:

  • Контроллеры для регистрации и входа пользователей.
  • Представления для страниц входа, регистрации и сброса пароля.
  • Маршруты, которые обеспечат доступ к этим страницам.

Установка зависимостей

Установите необходимые JavaScript зависимости и скомпилируйте ресурсы с помощью npm:

npm install && npm run build

В случае зависания установки запустите команду еще раз.

Удаление ненужных файлов и маршрутов

После установки пакета laravel/ui и настройки аутентификации, Laravel автоматически добавляет некоторые файлы и маршруты, которые не нужны в разработке админ-панели. Для очистки выполните следующие действия:

Контроллер HomeController

Контроллер HomeController.php, созданный по умолчанию, часто не используется, так как его функциональность заменяется вашими собственными контроллерами.

Для удаления выполните команду:

rm app/Http/Controllers/HomeController.php

Маршрут home из routes/web.php

Маршрут для домашней страницы также создается автоматически:

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

Его можно удалить из файла routes/web.php, так как теперь маршрут перенаправления для аутентификации определяется константой HOME в RouteServiceProvider.

Обновите свойство $redirectTo

В файлах контроллеров, которые отвечают за аутентификацию и авторизацию, нужно заменить строку, указывающую путь для перенаправления после успешного входа/регистрации, на константу RouteServiceProvider::HOME.

  1. Найдите и откройте файлы контроллеров:

Эти файлы находятся в папке app/Http/Controllers/Auth/ и включают в себя следующие файлы:

  • ConfirmPasswordController.php
  • LoginController.php
  • RegisterController.php
  • ResetPasswordController.php
  • VerificationController.php
  1. Импортируйте пространство имен в каждый контроллер с помощью оператора use:
use App\Providers\RouteServiceProvider;
  1. Измените свойство $redirectTo в каждом из этих контроллеров.

По умолчанию в Laravel свойство $redirectTo будет равно строке /home:

protected $redirectTo = '/home';

Нужно заменить это на:

protected $redirectTo = RouteServiceProvider::HOME;
  1. Пример изменения для контроллера.

Пример для LoginController.php:

namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
    use AuthenticatesUsers;
    protected $redirectTo = RouteServiceProvider::HOME;
    // Остальной код контроллера
}

Для других контроллеров, где есть свойство $redirectTo нужно аналогичным образом изменить строку.

Просмотр страниц

После завершения всех предыдущих шагов, чтобы протестировать отображение страницы входа и регистрации, выполните следующие действия:

Очистите кэш приложения:

php artisan config:clear

Команду php artisan нужно выполнять из корня проекта: /var/www/laravel-admin.

Откройте браузер и перейдите по следующим маршрутам:

http://<Публичный_IP-Адрес_Сервера>/login — для доступа к странице входа.

Image3

http://<Публичный_IP-Адрес_Сервера>/register — для регистрации нового пользователя.

Image2

Теперь базовая аутентификация в вашем проекте Laravel готова. Вы можете использовать её как основу для дальнейшей настройки и расширения.

Создание структуры файлов и папок для админ-панели

Создайте папку для шаблонов административной панели:

mkdir -p resources/views/dashboard/layouts

Создание базового шаблона

Создайте базовый шаблон resources/views/dashboard/layouts/master.blade.php:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,
initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Dashboard</title>
    <link
            href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.
min.css" rel="stylesheet">
    @stack('style')
</head>
<body class="container-fluid" style="height: 100%; margin: 0;">
<div class="wrapper row" style="height: 100%;">
    <nav id="sidebar" class="p-3 bg-dark d-flex flex-column col-2" style="height: 100vh;">
        @include('dashboard.layouts.sidebar')
    </nav>
    <div id="content" class="col" style="height: 100vh; overflow-y: auto;">
        @include('dashboard.layouts.nav')
        <div class="container-fluid mt-4 mb-4">
            @if(Session::has('global'))
                <div class="alert alert-success">
                    {{ Session::get('global') }}
                </div>
            @endif
            @yield('content')
        </div>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
@stack('scripts')
</body>
</html>

Описание ключевых элементов шаблона:

  • {{ csrf_token() }}: Генерирует уникальный токен для защиты от CSRF-атак.

  • @stack('style') и @stack('scripts'): Позволяют добавлять стили и скрипты из дочерних шаблонов через @push.

  • @include('dashboard.layouts.nav'): Подключает Blade-шаблон с верхним меню.

  • <script src="https://cdn.jsdelivr.net/npm/..."></script>: Для быстрого использования готовых стилей и компонентов на фронтенде, подключаем Bootstrap через CDN.

  • {{ Session::get('global') }}: Выводит уведомления из переменной global в сессии.

Создание вспомогательных шаблонов

Файл бокового меню resources/views/dashboard/layouts/sidebar.blade.php:

<ul class="nav flex-column">
    <li class="nav-item">
        <a class="nav-link text-white" href="{{ route('dashboard.home') }}">Главная</a>
    </li>
</ul>

Файл верхнего меню resources/views/dashboard/layouts/nav.blade.php:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container-fluid">
        <span class="navbar-brand">Dashboard</span>
    </div>
</nav>

Создание основного шаблона для страниц

Теперь создайте файл resources/views/dashboard/app.blade.php:

@extends('dashboard.layouts.master')
@section('content')
    <p>Как создать админку на Laravel: Пошаговое руководство</p>
@endsection

Этот файл наследует базовый шаблон master.blade.php и задает уникальный контент для каждой страницы.

После завершения всех предыдущих шагов, выполните следующие действия, чтобы протестировать работу аутентификации:

Для очистки кэшей и временных данных выполните команду в корне проекта:

php artisan optimize:clear

Теперь структура шаблонов для админ-панели завершена. Вы можете зарегистрировать первого пользователя, используя маршрут http://Публичный_IP-Адрес_Сервера/register.

Image4

После этого вы сможете авторизоваться.

Image5

Подготовка модели Post

Создание файлов модели и миграции

Создайте файл модели Post и файл миграцией (флаг -m) с помощью команды:

php artisan make:model Post -m

Laravel автоматически создаст два файла:

Файл модели app/Models/Post.php:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    use HasFactory;
}

Файл миграции для таблицы database/migrations/YYYY_MM_DD_create_posts_table.php:

database/migrations/YYYY_MM_DD_create_posts_table.php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
};

Файл миграции

Добавьте колонки title и content в файле database/migrations/YYYY_MM_DD_create_posts_table.php:

$table->string('title');
$table->text('content');

Вот так будет выглядеть файл миграции:

return new class extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
};

Выполните миграцию, чтобы создать таблицу в базе данных:

php artisan migrate

Файл модели Post

В файле app/Models/Post.php добавьте следующее свойство:

protected $fillable = ['title', 'content'];

Вот как будет выглядеть модель Post:

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];
}
  • $fillable — перечисляет поля, которые могут быть массово заполнены (mass assignment), например, через Post::create().

  • HasFactory — трейт, позволяющий использовать фабрики для тестирования.

Создание ресурсного контроллера

Создайте файл контроллера для модели Post с помощью команды:

php artisan make:controller Dashboard/PostController -r --model=Post

Laravel автоматически создаст файл контроллера app/Http/Controllers/Dashboard/PostController.php:

app/Http/Controllers/Dashboard/PostController.php

namespace App\Http\Controllers\Dashboards;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{

    public function index()
    {
        //
    }

    public function create()
    {
        //
    }
    
    public function store(Request $request)
    {
        //
    }
    
    public function show(Post $post)
    {
        //
    }
    
    public function edit(Post $post)
    {
        //
    }
    
    public function update(Request $request, Post $post)
    {
        //
    }
    
    public function destroy(Post $post)
    {
        //
    }
}

Что такое ресурсный контроллер?

Ресурсный контроллер (Resource Controller) в Laravel — это специальный тип контроллера, который автоматически создает пустые методы для стандартных операций CRUD (Create, Read, Update, Delete) над моделью данных. Это помогает упростить процесс создания маршрутов и контроллеров для управления ресурсами. Эти методы соответствуют RESTful-подходу и включают:

  • index — отображение списка записей.
  • create — форма для создания новой записи.
  • store — сохранение новой записи в базе данных.
  • edit — форма для редактирования записи.
  • update — обновление записи в базе данных.
  • destroy — удаление записи.

Обновление кода контроллера

Удалите метод show и обновите код методов index, create, store, edit, update и destroy в файле  контроллера app/Http/Controllers/Dashboard/PostController.php:

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::latest()->paginate(10);
        return view('dashboard.posts.index', compact('posts'));
    }

    public function create()
    {
        return view('dashboard.posts.create');
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required',
        ]);

        Post::create($request->only('title', 'content'));

  return redirect()->route('posts.index')->with('global', 'Запись успешно создана.');
    }

    public function edit(Post $post)
    {
        return view('dashboard.posts.edit', compact('post'));
    }

    public function update(Request $request, Post $post)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required',
        ]);

        $post->update($request->only('title', 'content'));

        return redirect()->route('posts.index')->with('global', 'Запись успешно обновлена.');
    }

    public function destroy(Post $post)
    {
        $post->delete();
        return redirect()->route('posts.index')->with('global', 'Запись успешно удалена.');
    }
}

Добавление маршрутов

В файле routes/dashboard.php добавьте маршрут для ресурсного контроллера:

use App\Http\Controllers\Dashboard\PostController;

Route::resource('posts', PostController::class);

Этот маршрут автоматически создаст доступ к методам ресурсного контроллера, таким как index, create, store, и т. д.

Добавление ссылки в сайдбар

В файле resources/views/dashboard/layouts/sidebar.blade.php добавьте ссылку на управление постами:

<li class="nav-item">
<a class="nav-link text-white" href="{{ route('posts.index') }}">Записи</a>
</li>

Вот как будет выглядеть файл sidebar.blade.php:

<ul class="nav flex-column">
    <li class="nav-item">
        <a class="nav-link text-white" href="{{ route('dashboard.home') }}">Главная</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-white" href="{{ route('posts.index') }}">Записи</a>
    </li>
</ul>

Объяснение {{ route('posts.index')}}

Когда добавляете ресурсный маршрут:

Route::resource('posts', PostController::class);

Laravel автоматически создает несколько маршрутов для методов в контроллере PostController. Эти маршруты будут иметь следующие имена:

  • posts.index — для отображения списка постов (метод index).
  • posts.create — для отображения формы создания поста (метод create).
  • posts.store — для сохранения нового поста в базе данных (метод store).
  • posts.edit — для отображения формы редактирования поста (метод edit).
  • posts.update — для обновления поста в базе данных (метод update).
  • posts.destroy — для удаления поста (метод destroy).

Теперь в меню админки появится пункт «Записи», который ведёт на страницу управления постами.

Класс Request: создание и использование

Класс Request в Laravel отвечает за управление входящими HTTP-запросами. Он обеспечивает:

  • Централизацию валидации: Правила проверки данных определяются в одном месте, что повышает читаемость и упрощает поддержку.

  • Безопасность: Гарантирует, что только валидированные данные попадут в контроллер.

  • Логическую изоляцию: Убирает из контроллеров лишнюю логику, делая код более чистым и понятным.

Что делает класс Request?

  1. Валидация данных: В классе Request вы описываете правила проверки данных. Например, требование, чтобы поле title было обязательным и содержало строку определенной длины.

  2. Авторизация: Класс позволяет определить, кто может выполнять запрос. Если авторизация в методе authorize возвращает false, запрос будет отклонен с кодом 403.

  3. Чистота данных: Метод validated() возвращает только те данные, которые прошли проверку. Это предотвращает попадание нежелательных данных в базу или логику приложения.

  4. Изоляция логики: Все правила, связанные с запросом, изолируются в классе Request, уменьшая сложность контроллера.

Создание кастомного класса Request

Чтобы создать кастомный класс Request для модели Post, выполните команду:

php artisan make:request PostRequest

Laravel автоматически создаст файл app/Http/Requests/PostRequest.php:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class PostRequest extends FormRequest
{
    public function authorize()
    {
        return false;
    }

    public function rules()
    {
        return [
            //
        ];
    }
}

Обновите методы authorize и rules:

class PostRequest extends FormRequest
{
    /**
     * Определяет, может ли пользователь отправить запрос.
     */
    public function authorize()
    {
        return true; // Замените на проверку, если требуется авторизация.
    }

    /**
     * Определяет правила валидации входящих данных.
     */
    public function rules()
    {
        return [
            'title' => 'required|string|max:255',
            'content' => 'required',
        ];
    }

    /**
     * Сообщения об ошибках валидации.
     */
    public function messages()
    {
        return [
            'title.required' => 'Поле "Заголовок" обязательно для заполнения.',
            'content.required' => 'Поле "Контент" обязательно для заполнения.',
        ];
    }
}

В некоторых случаях полезно создавать два разных класса запроса для операций создания и обновления записи. Это может быть полезно, если правила валидации для этих операций различаются.

  1. PostStoreRequest — используется для валидации данных при создании нового поста.
  2. PostUpdateRequest — используется для валидации данных при обновлении существующего поста.

Это позволяет настраивать разные правила валидации для этих операций. Например, при обновлении записи поле title может быть необязательным, если оно не изменяется, тогда как при создании оно обязательно.

Использование класса PostRequest в контроллере PostController

В контроллере app/Http/Controllers/Dashboard/PostController.php выполните следующие действия:

  1. Импортируйте пространство имен с помощью оператора use:
use App\Http\Requests\PostRequest;
  1. Обновите методы store и update, чтобы использовать новый класс app/Http/Requests/PostRequest.php:
namespace App\Http\Controllers\Dashboard;

use App\Http\Controllers\Controller;
use App\Models\Post;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{
    
// Остальные методы

public function store(PostRequest $request)
    {
        Post::create($request->validated());

        return redirect()->route('posts.index')->with('global', 'Запись успешно создана.');
    }


    public function update(PostRequest $request, Post $post)
    {
        $post->update($request->validated());

        return redirect()->route('posts.index')->with('global', 'Запись успешно обновлена.');
    }

// Остальные методы

}

Что делает $request->validated()?

Метод $request->validated() используется для получения только тех данных из запроса, которые прошли валидацию. Когда вы используете кастомный класс запроса, Laravel автоматически выполняет все проверки, описанные в методе rules() класса запроса. Например, может быть проверена обязательность полей или их соответствие заданному формату.

Метод validated() возвращает массив данных, которые успешно прошли валидацию, исключая любые поля, которые не прошли проверки. Это защищает от небезопасных данных и помогает избежать ошибок при обработке.

Пример:

  • Если запрос содержит поле title, которое не соответствует правилам валидации, Laravel прервет выполнение метода и вернет ошибку. Например, это произойдет, если поле пустое, хотя по правилам оно обязательно.
  • В случае успешной валидации $request->validated() вернет только те поля, которые прошли все проверки, и их можно безопасно передать для создания или обновления записи в базе данных.

Создание Blade-шаблонов

Создайте папку для шаблонов модели Post:

mkdir -p resources/views/dashboard/posts

Создайте шаблон для отображения всех элементов модели resources/views/dashboard/posts/index.blade.php:

@extends('dashboard.layouts.master')
@section('content')
    <div class="d-flex justify-content-between align-items-center">
        <h1>Записи</h1>
        <a href="{{ route('posts.create') }}" class="btn btn-primary">Создать запись</a>
    </div>
    <table class="table mt-4">
        <thead>
        <tr>
            <th>#</th>
            <th>Заголовок</th>
            <th>Действия</th>
        </tr>
        </thead>
        <tbody>
        @foreach($posts as $post)
            <tr>
                <td>{{ $post->id }}</td>
                <td>{{ $post->title }}</td>
                <td>
                    <a href="{{ route('posts.edit', $post) }}" class="btn btn-warning btn-sm">Редактировать</a>
                    <form action="{{ route('posts.destroy', $post) }}" method="POST" class="d-inline-block">
                        @csrf
                        @method('DELETE')
                        <button class="btn btn-danger btn-sm" onclick="return confirm('Вы уверены?')">Удалить</button>
                    </form>
                </td>
            </tr>
        @endforeach
        </tbody>
    </table>
    {{ $posts->links() }}
@endsection

Шаблон с формой для создания элементов resources/views/dashboard/posts/create.blade.php:

@extends('dashboard.layouts.master')
@section('content')
    <h1>Создать запись</h1>
    <form action="{{ route('posts.store') }}" method="POST">
        @csrf
        <div class="mb-3">
            <label for="title" class="form-label">Заголовок</label>
            <input type="text" class="form-control" id="title" name="title" value="{{old('title')}}">
            @error('title')
             <p class="text-danger">{{ $message }}</p>
            @enderror
        </div>
        <div class="mb-3">
            <label for="content" class="form-label">Контент</label>
            <textarea class="form-control" id="content" name="content" rows="5">{{old('content')}}</textarea>
            @error('content')
            <p class="text-danger">{{ $message }}</p>
            @enderror
        </div>
        <button type="submit" class="btn btn-success">Сохранить</button>
    </form>
@endsection

Шаблон для редактирования элемента модели resources/views/dashboard/posts/edit.blade.php:

@extends('dashboard.layouts.master')
@section('content')
    <h1>Редактировать запись</h1>
    <form action="{{ route('posts.update', $post) }}" method="POST">
        @csrf
        @method('PUT')
        <div class="mb-3">
            <label for="title" class="form-label">Заголовок</label>
            <input type="text" class="form-control" id="title" name="title" value="{{old('title', $post->title)}}">
            @error('title')
            <p class="text-danger">{{ $message }}</p>
            @enderror
        </div>
        <div class="mb-3">
            <label for="content" class="form-label">Контент</label>
            <textarea class="form-control" id="content" name="content" rows="5">{{old('content', $post->content)}}</textarea>
            @error('content')
            <p class="text-danger">{{ $message }}</p>
            @enderror
        </div>
        <button type="submit" class="btn btn-success">Обновить</button>
    </form>
@endsection

Объяснение основных элементов шаблонов

@extends

@extends используется для наследования базового шаблона.

В данном случае шаблоны страниц index.blade.php, create.blade.php и edit.blade.php наследуют базовый шаблон master.blade.php, который определяет общий каркас страницы (шапка, меню, стили, скрипты и т.д.). Это позволяет переиспользовать общие части интерфейса и сократить дублирование кода.

@section

@section используется для заполнения секций, определенных в базовом шаблоне через @yield. Например, в базовом шаблоне master.blade.php определена секция @yield('content'), которая динамически заменяется содержимым дочерних шаблонов.

{{ old('title') }}

old() используется для получения ранее введенного значения формы после перезагрузки страницы. Это особенно полезно, если при отправке формы произошли ошибки валидации, и важно сохранить введенные пользователем данные.

@error

@error используется для вывода сообщений об ошибках валидации для определенного поля. Если поле title не прошло проверку, то внутри блока @error('title') будет отображено сообщение об ошибке.

Попробуйте создать и отредактировать несколько постов

После того как вы создадите шаблоны для отображения, создания и редактирования постов, не забудьте протестировать их в действии. Создайте несколько записей, используя форму на странице Создать запись, и попробуйте редактировать их через соответствующую форму.

Убедитесь, что все работает корректно: можно добавлять новые посты, а также редактировать уже существующие записи. Также проверьте, что сообщения об ошибках правильно отображаются при неверно заполненных полях.

Вывод записей в клиентской части

Создайте контроллер для обработки запросов:

php artisan make:controller PostController

Импортируйте пространство имен App\Models\Post и  добавьте метод show в контроллере app/Http/Controllers/PostController.php для получения записей из базы данных:

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function show()
    {
        $posts = Post::latest()->paginate(10); // Пагинация для удобного отображения
        return view('posts.index', compact('posts'));
    }
}

Добавьте маршрут для отображения списка записей.

Откройте файл routes/web.php.

В этом файле находятся маршруты для клиентской части вашего приложения.

Используйте контроллер app/Http/Controllers/Controller.php для обработки запросов на главной странице:

use App\Http\Controllers\PostController;

Замените существующий маршрут главной страницы.

Было:

Route::get('/', function () {
    return view('welcome');
});

Стало:

Route::get('/', [PostController::class, 'show'])->name('posts.index');

Этот шаг настраивает главную страницу приложения для отображения записей из базы данных.

Создайте Blade-шаблон для вывода записей.

Создайте папку posts:

mkdir -p resources/views/posts

Создайте файл resources/views/posts/index.blade.php:

@extends('layouts.app')
@section('content')
<div class="container mt-4">
    <h1>Список записей</h1>
    @foreach($posts as $post)
        <div class="card mb-3">
            <div class="card-body">
                <h5 class="card-title">{{ $post->title }}</h5>
                <p class="card-text">{{$post->content}}</p>
            </div>
        </div>
    @endforeach
    <div class="mt-4">
        {{ $posts->links() }}
    </div>
</div>
@endsection

Теперь на главной странице http://localhost:8000/ вы сможете увидеть список записей с их заголовками и содержанием.

Image1

Для загрузки изображений к постам в облачное хранилище S3 воспользуйтесь инструкцией Интеграция Laravel с S3-хранилищем Timeweb Cloud.

Запустите свое приложение на облачном сервере

Заключение

Вы создали базовую админ-панель и клиентскую часть на Laravel! Ваш проект теперь включает:

  1. Админ-панель: Для управления записями через CRUD-интерфейс.
  2. Клиентскую часть: Для отображения списка записей пользователям.
  3. Гибкость и масштабируемость: Использование кастомных классов Request и моделей.
  4. Готовность к дальнейшему развитию: Вы можете добавлять новые функции, такие как категории, теги, поиск и фильтры.
Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
31 января 2025 г.
141
29 минут чтения
Средний рейтинг статьи: 3.3
Пока нет комментариев