Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.
Кратко о задаче
Создайте пользователя lara и добавьте его в группы sudo и www-data:
adduser lara
usermod -aG sudo lara
usermod -aG www-data lara
su - laraУстановка PHP 8.3 и расширений для Laravel
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Скачайте установочный скрипт:
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;"
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
sudo composer self-update 2.7.8
sudo apt purge nodejs -y
sudo apt autoremove -y
sudo apt update
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejsСоздание рабочей директории
Создайте папку для проекта:
cd /var
sudo mkdir www
sudo chown lara:www-data www
sudo chmod 775 www
cd wwwУстановка и настройка 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
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 нужно выполнять из корня проекта: /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'));
});
}
// Остальной код провайдера
}Основные изменения и настройки
Определяет маршрут перенаправления для авторизованных пользователей после успешной аутентификации. В данном случае пользователи будут направлены на /dashboard. Это удобно для централизованного управления перенаправлением: если маршрут изменится, достаточно будет обновить только значение константы.
public const HOME = '/dashboard';В методе 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');-
Route::get('/'): Этот маршрут отвечает на GET-запросы по адресу/dashboard(так как вRouteServiceProviderдля административной панели установлен префиксdashboard). -
Функция обратного вызова (
callback): В функции обратного вызова возвращается вид (view)dashboard.app. Это базовый шаблон административной панели, который был создан ранее и наследует структуру изmaster.blade.php. -
Именование маршрута:
->name('dashboard.home'). Именование маршрута позволяет обращаться к нему по имениdashboard.homeв шаблонах, контроллерах или при создании ссылок. Например, в Blade-шаблонах:<a href="{{ route('dashboard.home') }}">Главная</a>.
Route::get('/'): Этот маршрут отвечает на GET-запросы по адресу /dashboard (так как в RouteServiceProvider для административной панели установлен префикс dashboard).
Функция обратного вызова (callback): В функции обратного вызова возвращается вид (view) dashboard.app. Это базовый шаблон административной панели, который был создан ранее и наследует структуру из master.blade.php.
Именование маршрута: ->name('dashboard.home'). Именование маршрута позволяет обращаться к нему по имени dashboard.home в шаблонах, контроллерах или при создании ссылок. Например, в Blade-шаблонах: <a href="{{ route('dashboard.home') }}">Главная</a>.
-
Это главная страница административной панели.
-
Этот маршрут используется для рендеринга базового шаблона административной панели, который можно настроить и наполнить необходимым содержимым.
Это главная страница административной панели.
Этот маршрут используется для рендеринга базового шаблона административной панели, который можно настроить и наполнить необходимым содержимым.
Для использования стандартных фронтенд-стилей и аутентификации в Laravel, необходимо установить пакет laravel/ui. Этот пакет предоставляет базовые компоненты, такие как аутентификация, страницы входа и регистрации, а также позволяет использовать фронтенд-фреймворки, такие как Bootstrap или Vue.js.
Установка пакета laravel/ui
Установите пакет laravel/ui через Composer:
composer require laravel/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.php, созданный по умолчанию, часто не используется, так как его функциональность заменяется вашими собственными контроллерами.
Для удаления выполните команду:
rm app/Http/Controllers/HomeController.phpМаршрут для домашней страницы также создается автоматически:
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');Его можно удалить из файла routes/web.php, так как теперь маршрут перенаправления для аутентификации определяется константой HOME в RouteServiceProvider.
Обновите свойство $redirectTo
В файлах контроллеров, которые отвечают за аутентификацию и авторизацию, нужно заменить строку, указывающую путь для перенаправления после успешного входа/регистрации, на константу RouteServiceProvider::HOME.
- Найдите и откройте файлы контроллеров:
Эти файлы находятся в папке app/Http/Controllers/Auth/ и включают в себя следующие файлы:
ConfirmPasswordController.phpLoginController.phpRegisterController.phpResetPasswordController.phpVerificationController.php
- Импортируйте пространство имен в каждый контроллер с помощью оператора
use:
use App\Providers\RouteServiceProvider;- Измените свойство
$redirectToв каждом из этих контроллеров.
По умолчанию в Laravel свойство $redirectTo будет равно строке /home:
protected $redirectTo = '/home';
protected $redirectTo = RouteServiceProvider::HOME;- Пример изменения для контроллера.
Пример для 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 нужно выполнять из корня проекта: /var/www/laravel-admin.
Откройте браузер и перейдите по следующим маршрутам:
http://<Публичный_IP-Адрес_Сервера>/login — для доступа к странице входа.
http://<Публичный_IP-Адрес_Сервера>/register — для регистрации нового пользователя.
Теперь базовая аутентификация в вашем проекте Laravel готова. Вы можете использовать её как основу для дальнейшей настройки и расширения.
Создание структуры файлов и папок для админ-панели
Создайте папку для шаблонов административной панели:
mkdir -p resources/views/dashboard/layoutsСоздание базового шаблона
Создайте базовый шаблон resources/views/dashboard/layouts/master.blade.php:
Описание ключевых элементов шаблона :
-
{{ 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в сессии.
{{ 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.
После этого вы сможете авторизоваться.
Создание файлов модели и миграции
Создайте файл модели Post и файл миграцией (флаг -m) с помощью команды:
php artisan make:model Post -mLaravel автоматически создаст два файла:
Файл модели 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');
}
};Выполните миграцию, чтобы создать таблицу в базе данных:
В файле 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— трейт, позволяющий использовать фабрики для тестирования.
$fillable — перечисляет поля, которые могут быть массово заполнены (mass assignment), например, через Post::create().
HasFactory — трейт, позволяющий использовать фабрики для тестирования.
Создание ресурсного контроллера
Создайте файл контроллера для модели Post с помощью команды:
php artisan make:controller Dashboard/PostController -r --model=PostLaravel автоматически создаст файл контроллера app/Http/Controllers/Dashboard/PostController.php:
Что такое ресурсный контроллер?
Ресурсный контроллер (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?
-
Валидация данных : В классе
Requestвы описываете правила проверки данных. Например, требование, чтобы полеtitleбыло обязательным и содержало строку определенной длины. -
Авторизация : Класс позволяет определить, кто может выполнять запрос. Если авторизация в методе
authorizeвозвращаетfalse, запрос будет отклонен с кодом 403. -
Чистота данных : Метод
validated()возвращает только те данные, которые прошли проверку. Это предотвращает попадание нежелательных данных в базу или логику приложения. -
Изоляция логики : Все правила, связанные с запросом, изолируются в классе
Request, уменьшая сложность контроллера.
Валидация данных : В классе Request вы описываете правила проверки данных. Например, требование, чтобы поле title было обязательным и содержало строку определенной длины.
Авторизация : Класс позволяет определить, кто может выполнять запрос. Если авторизация в методе authorize возвращает false, запрос будет отклонен с кодом 403.
Чистота данных : Метод validated() возвращает только те данные, которые прошли проверку. Это предотвращает попадание нежелательных данных в базу или логику приложения.
Изоляция логики : Все правила, связанные с запросом, изолируются в классе Request, уменьшая сложность контроллера.
Создание кастомного класса Request
Чтобы создать кастомный класс Request для модели Post, выполните команду:
php artisan make:request PostRequestLaravel автоматически создаст файл 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' => 'Поле "Контент" обязательно для заполнения.',
];
}
}В некоторых случаях полезно создавать два разных класса запроса для операций создания и обновления записи. Это может быть полезно, если правила валидации для этих операций различаются.
PostStoreRequest— используется для валидации данных при создании нового поста.PostUpdateRequest— используется для валидации данных при обновлении существующего поста.
Это позволяет настраивать разные правила валидации для этих операций. Например, при обновлении записи поле title может быть необязательным, если оно не изменяется, тогда как при создании оно обязательно.
Использование класса PostRequest в контроллере PostController
В контроллере app/Http/Controllers/Dashboard/PostController.php выполните следующие действия:
- Импортируйте пространство имен с помощью оператора
use:
use App\Http\Requests\PostRequest;- Обновите методы
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()вернет только те поля, которые прошли все проверки, и их можно безопасно передать для создания или обновления записи в базе данных.
Создайте папку для шаблонов модели 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 используется для наследования базового шаблона.
В данном случае шаблоны страниц index.blade.php, create.blade.php и edit.blade.php наследуют базовый шаблон master.blade.php, который определяет общий каркас страницы (шапка, меню, стили, скрипты и т.д.). Это позволяет переиспользовать общие части интерфейса и сократить дублирование кода.
@section используется для заполнения секций, определенных в базовом шаблоне через @yield. Например, в базовом шаблоне master.blade.php определена секция @yield('content'), которая динамически заменяется содержимым дочерних шаблонов.
old() используется для получения ранее введенного значения формы после перезагрузки страницы. Это особенно полезно, если при отправке формы произошли ошибки валидации, и важно сохранить введенные пользователем данные.
@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-шаблон для вывода записей.
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/ вы сможете увидеть список записей с их заголовками и содержанием.
Для загрузки изображений к постам в облачное хранилище S3 воспользуйтесь инструкцией Интеграция Laravel с S3-хранилищем Simple-Server.
Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.