Автореферат

Наименование Разработка веб-приложений

Автор А.В.Михалькевич

Специальность Разработка веб-приложения с помощью стэка TALL: TailwindCSS, AlpineJS, Laravel и Livewire,

Анотация

Теория и практика веб-разработки.

Anotation in English

Theory and practice of web development.

Ключевые слова web, laravel, web-development, web-creator, site

Количество символов 69943

Содержание

Введение

1 Начало разработки

Начинаем разработку с изучения основных технологий и выбранной архитектуры веб-приложерия.

MVC означает Модель-Представление-Контроллер.

Вопросы: Что такое PHP?

1 .1 Фрэймворк Laravel

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

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

Laravel построен в соответствии с архитектурой MVC, где Model (Модель) это данные, View (Представление) - элементы шаблонов, представление, Controller (контроллер) обрабатывает запросы пользователей и бизнес-логику.

Laravel можно установить с помощью composer.

Composer это менеджер зависимостей и установщик PHP пакетов.

Сделать это можно с помощью этой команды

composer create-project --prefer-dist laravel/laravel 
После установки, необходимо в консоли перейти в папку с проектом и с помощью команды Artisan запустить приложение
php artisan serve
Вопросы: Что такое Laravel? Что такое composer? Как создать новый проект Laravel Объясните архитектуру MVC в Laravel. Назовите модуль администрирования и опишите принцип его использования Опишите процесс разработки backend API.

1 .2 Маршруты сайта и контроллеры

Определить маршруты приложения можно в файле routes/web.php или routes/api.php.

Для определения маршрутов имеется специальный фасад Route. Пример:

Route::get('/path', 'Controller@method').

Контроллеры в Laravel это классы HTTP запросов. Они реализуют любую логику и вывод (response).

Кроме обычных контроллеров, Laravel позволяет создавать api-контроллеры и ресурные контроллеры. Отличие их в следующем: api-контроллер уже содержат методы для реализации CRUD-запросов (Create, Read, Update, Delete); ресурсный контроллер помимо этих методов содержит еще два метода, реализующие формы создания и редактирования; а при создании обычного контроллера, мы получаем пустой класс.

Создание обычного контроллера

php artisan make:controller ProductController

Создание api-контроллера

php artisan make:controller ProductController --api

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

php artisan make:controller ProductController --resource

Из экшна (или метода) контроллера мы можем передать данные в view с помощью compact()

return view('index', compact('products'));

Методы маршрутизатора

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);

Где:

get - вывод данных

post - вставка данных

put и patch - обновление данных

delete - удаление

И put, и patch используются для обновления ресурсов, но put обычно заменяет весь ресурс, а patch обновляет определенные поля.

При определении нескольких маршрутов, которые используют один и тот же URI, маршруты, использующие методы get, post, put, patch, delete и options, должны быть определены перед маршрутами, использующими методы any, match и redirect. Это гарантирует, что входящий запрос соответствует правильному маршруту.

Вопросы: Как определить маршрут в Laravel? Для чего нужны контролеры? Объясните разницу между ресурсным контроллером и api-контроллером Как передать данные из контроллера в шаблон? Какова команда для создания нового контроллера и какие дополнительные флаги возможно использовать при создании контроллера? Объясните разницу между методами запросов put и patch Что это такое и как создать ресурсный контроллер?

1 .3 База данных и модели

База данных

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

В частности, Laravel поддерживает четыре базы данных:

  • MySQL
  • Postgres
  • SQLite
  • SQL Server

Подключение к базе данных осуществляется в корневом файле .env.

Данный файл содержит переменные окружения. Если данный файл отстутствует, его необходимо создать (например, по примеру env.example) и выполнить команду по сгенерированию секретного ключа.

php artisan key:generate

Эта команда сгенерирует значение переменной окружения APP_KEY. Для создания криптографически безопасного ключа будет использован безопасный генератор случайных байтов PHP. Обычно это значение переменной среды APP_KEY генерируется автоматически во время установки Laravel.

Модели

Модель Eloquent — это класс, представляющий таблицу базы данных. Он используется для взаимодействия с базой данных, включая выполнение запросов, определение связей и инкапсуляцию логики таблицы. Модель можно создать с помщью Artisan

php artisan make:model Product

По умолчанию, все таблицы базы данных должны заканчиваться на 's' (что указывает на множественность хранимых данных), тогда происходит автоматическая ассоциация моделей с таблицей. Единственное отличие - в названиях моделей отсутствует окончание ввиде буквы 's'. Класс Модели предназначен для создания объектов, но класс один - отсюда единственное число в названии модели.

Изменить имя таблицы модели можно переопределив свойство $table модели:

class User extends Eloquent{  
protected $table="my_user_table";  
} 

 

Вопросы: Для чего нужен файл .env? Перечислите базы данных, поддерживаемые Laravel. Как реализовать в моделях связи belongsTo и hasMany? Что такое цепочка методов в Laravel? Зачем нужен метод with в Eloquent? Какие типы связей есть в Laravel? И в каких случаях они используются? Каковы различия между отношениями hasMany и hasManyThrough в Laravel и в каких случаях они используются? Как можно оптимизировать запросы к базе данных в отношениях Laravel, чтобы избежать проблемы N+1, и почему это важно? Что такое полиморфные отношения в Laravel и когда они используются?

1 .3 .1 Фабрики моделей

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

Хоть и при помощи сидов можно создать несколько записей, но фабрика моделей генерирует множество.

Файлы фабрик моделей хранятся в папке database/factories, и там уже есть один готовый файл UserFactory.php — фабрика для модели User. В Laravel вызываемый метод definition() выглядит так:

    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'email' => $this->faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }

Из сидера фабрику можем вызвать так:

    public function run()
    {
        \App\Models\User::factory(10)->create();
    }

Далее запускаем сидер:

php artisan db:seed

Стоит так же отметить, что запускать фабрики мы можем не только из сидов, но и из других мест приложения. Например, из консоли. Для этого, сперва надо войти в tinker:

php artisan tinker

После полученного приглашения, можно выполнить фабрику:

\App\Models\User::factory(10)->create();
Вопросы: В какой папке хранятся фабрики моделей и для чего они нужны?

1 .3 .2 Связи моделей

Связи моделей

Eloquent предлагает встроенный механизм связывания моделей. Вот поддерживаемые типы связей:

  • One to One
  • One to Many
  • One to Many (Inverse)
  • Many to Many
  • Has Many Through
  • Polymorphic Relations
  • Many To Many Polymorphic Relations

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

    public function products(){
        return $this->hasMany(Catalog::class, 'parent_id');
    }

Пример обратной связи в модели Product. Продукт принадлежит каталогу:

    public function catalog(){
        return $this->belongsTo(Catalog::class);
    }

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

$products = Product::with('catalogs')->get();
foreach ($products as $product) {
 echo $book->author->name;
}

Результирующий sql-запрос будет примерно таким:

select * from products
select * from catalogs where id in (1, 2, 3, 4, 5, …)

Разница между hasMany hasManyThrough

Причём, hasMany и hasManyThrough используются в разных случаях:

hasMany: устанавливает связь «один ко многим» между двумя моделями напрямую. Например, у пользователя много сообщений. Используется, когда между двумя моделями существует прямая связь.

hasManyThrough: используется, когда существует промежуточная модель, соединяющая две другие модели. Он часто используется для сложных отношений, когда чтобы получить нужные связанные данные, необходимо пройти через несколько таблиц. Например, пользователь может иметь много публикаций посредством модели подписки. Или Каталог содержит множество товаров и каждый товар может присутствовать во множестве каталогов. В таких случаях создаётся промежуточная таблица, в которой хранятся данные связей, и метод hasManyThrought связывает две необходимые модели через промежуточную таблицу, для которой даже нет необходимости создавать модель.

1 .4 Шаблонизатор blade

Представления, View - это конечная точка запроса пользователя (см. MVC и HMVC). Вместе с тем, представления - это цель запроса: пользователь, нажимая на кнопку ожидает что-то, увидеть представление.

Ответственность за формирование ответа в Laravel берет на себя шаблонизатор blade, который встроен в Laravel по-умолчанию.

Шаблоны создаются в папке app/views и имеют расширение blade.php. Шаблоны подключаются в экшне через хелпер view(), входящим параметром в который передается имя шаблона без расширения blade.php.

Сперва создадим в папке view папку layouts для хранения базовых шаблонов. В папке layouts создадим файл defaults.blade.php. Данный файл содержит html-код шаблона приложения. Меняющуюся часть помещаем в диррективу @yield

начало html-кода неизменной части приложения
@yield('content')
окончание html-кода неизменной части приложения

Меняющуюся часть шаблона вынесем в отдельный файл index.blade.php.

@extends('layouts.default')
@section('content')
html-код меняющейся части приложения
@stop

Обратите внимание на @extends в начале шаблона. Данная дирректива определяет файл базового шаблона.

Подключение подшаблона index.blade.php осуществляется в экшне контроллера.

namespace App\Http\Controllers;
use Illuminate\Http\Request;
class BaseController extends Controller
{
  public function index(){
   return view('index');
  }
}

Существует несколько способов передачи переменных из экшна в подшаблон. Рассмотрим их. Передадим переменные $url и $title:

  public function index($url){
   return view('index', ['url' => $url, 'title'=>'Добро пожаловать на сайт']);
  }
  public function index($url){
   return view('index')->with('url', $url)->with('title', 'Добро пожаловать на сайт');
  }
  public function index($url){
   return view('index')->withUrl('url')->withTitle('title');
  }
  public function index($url){
   $title = 'Добро пожаловать на сайт';
   return view('index', compact('url', 'title'));
);
  }

Наилучший способ - compact(), т.к. он содержит меньше кода.

Диррективы Blade

@ функции, циклы

{{ }} вывод переменной не содержащей html

{!! !!} вывод переменной содержащей html-код

Папка для хранения шаблонов - resources/views

По умолчанию, Laravel использует шаблонизатор blade. Blade является частью MVC-архитектуры, его задача - реализация View (представлений и элементов представлений).

Blade - шаблонизатор, который сокращет код, разбивает представление на элементы и представляет возможность повторного использования элементов шаблона.

Вопросы: Что такое Blade в Laravel?

1 .5 Middleware в MVC

Middleware или промежуточное программное обеспечение — это фильтр HTTP-запросов.

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

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

В Laravel доступно два типа промежуточного программного обеспечения:

  • Глобальное программное обеспечение. Будет запускаться при каждом HTTP-запросе приложения.
  • Промежуточное программное обеспечение маршрутизации. Будет закреплен за конкретным маршрутом.
Команда для создания middleware:
php artisan make:middlewareUserMiddleware
Вопросы: Зачем middleware в MVC?

1 .6 Миграции

Миграции

Миграции — это способ управления структурами таблиц базы данных и внесения в нее изменений с течением времени.

Вы можете создавать и запускать миграции с помощью команд Artisan. Файл миграции включает в себя два метода: up() и down(). Метод up() используется для добавления новых таблиц, столбцов или индексов базы данных, а метод down() используется для отмены операций, выполняемых методом up(). Пример создания миграции для таблицы accounts:

php artisan make:migration Accounts

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

php artisan make:model Account -m

Мягкое удаление моделей

По умолчанию в Laravel при удалении записи через модель, удаляется и строка с данными в базе данных. Laravel также поддерживает механизм мягкого удалния. При таком удалении, модель просто перестаёт "видеть" строку с этими данными, сами данные остаются в базе, но они содержат метку - дата удаления.

Для создания мягкого удаления, необходимо в модель подключить типаж SoftDeletes

namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
 
class Flight extends Model
{
    use SoftDeletes;
}

Также необходимо добавить в модель поле deleted_at

Сделать это можно с помощью миграции

//создать поле deleted_at
Schema::table('flights', function (Blueprint $table) {
    $table->softDeletes();
});
//удалить поле deleted_at если оно есть 
Schema::table('flights', function (Blueprint $table) {
    $table->dropSoftDeletes();
});
Вопросы: Что такое миграции в Laravel? Как создать модель? Как создать миграцию для добавления полей в существующую таблицу?

1 .7 Request валидация

Самое простое решение для валидации использовать метод validate, предоставляемый объектом Illuminate\Http\Request. Если правила валидации будут пройдены, то код продолжит нормально выполняться; однако, если проверка не пройдена, то будет создано исключение Illuminate\Validation\ValidationException и соответствующий ответ об ошибке будет автоматически отправлен обратно пользователю.

Если валидации не пройдена во время традиционного HTTP-запроса, то будет сгенерирован ответ-перенаправление на предыдущий URL-адрес. Если входящий запрос является XHR-запросом, то будет возвращен JSON-ответ, содержащий сообщения об ошибках валидации.

Чтобы лучше понять метод validate, давайте вернемся к методу store:

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

    // Запись блога корректна ...
}

Имеется возможность создавать собственные правила проверки, расширив класс Validator и зарегистрировав правило у поставщика услуг.

Помимо самих данных форм, объект request содержит дополнительные данные, например ip пользователя:

// в классах:
$clientIP = \Request::ip(); dd($clientIP);
// или в blade:
request()->ip()
Вопросы: Как валидировать данные формы? Как создать собственное правило валидации в Laravel? Как узнать ip пользователя?

1 .8 Service providers

Service providers или Поставщики услуг — это способ загрузки и регистрации сервисов в сервисном контейнере Laravel. Они помогают управлять зависимостями и настраивать различные компоненты приложения. Рассмотрим artisan команду, которую можно использовать для создания поставщика услуг:

php artisan make:provider ClientsServiceProvider

 Классы поставщиков услуг extend  Illuminate\Support\ServiceProviderclass. Класс поставщика услуг содержит два основных метода

  • register()
  • boot()

В методе register() следует привязывать элементы только к сервисному контейнеру.

Зарегистрировать какие-либо прослушиватели событий, маршруты или любую другую функциональность пишем в методе boot().

Вопросы: Что такое service providers?

1 .9 Seeders

Первоначальные данные, seeders используются для заполнения таблиц базы реальными данными. Создавать и запускать на выполнение можем с помощью Artisan. Процесс работы с сидерами таков:

1. создать сидер:

php artisan make:seeder CatalogSeeder

2. заполнить данными.

3. запустить на выполнение:

php artisan db:seed
Вопросы: Как создать seeder для базы данных?

1 .10 Внедрение зависимостей

Laravel Container — мощный инструмент для управления зависимостями и хранения объектов для различных целей.

Внедрение зависимостей обычно используется в Laravel. Даже доступ к Request мы в основном внедряем.

public function __construct (Request $ request) 
Вопросы: Объясните концепцию внедрения зависимости (Dependency Injection).

1 .11 Защита форм

Для защиты форм от межсайтовых подделок запросов (csrf: cross-site request forgery) Laravel имеет специальный хелпер.

@csrf

Защита CSRF означает защиту от подделки межсайтовых запросов.

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

Чтобы отключить защиту CSRF для определенного маршрута, необходимо добавить этот конкретный URL-адрес или маршрут в переменную $except, которая присутствует в файле app\Http\Middleware\VerifyCsrfToken.php. Вот пример того, как удалить защиту csrf на маршрутах и URL-адресах в laravel:

classVerifyCsrfToken extends BaseVerifier  
{  
protected $except = [  
          'Pass here your URL',  
      ];  
}
Вопросы: Как создать csrf-токен? Как отключить проверку csrf-токена для определённого маршрута?

2 Фронтенд для Laravel

Продолжаем разработку, подключая фронтенд

2 .1 Vite

Vite - это локальная среда разработки фронтенд-приложений.

В Laravel он в основном используется для объединения ресурсов CSS и JavaScript. Laravel предлагает плагин NPM и директиву Blade. Оба они включены в приложения Laravel «из коробки», и поставляются с файлом конфигурации: vite.config.js.

Вопросы: Для чего нужен Artisan?

2 .1 .1 Vite для Laravel

Так выглядит vite.config.js по умолчанию, после установки Laravel

import { defineConfig } from 'vite';
import laravel, { refreshPaths } from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: [
                ...refreshPaths,
                'app/Livewire/**',
            ],
        }),
    ],
});

Если компоненты Livewire не используются, то необходимо изменить параметр refresh

...
  refresh: true,
...

Конфигурационный файл определяет плагины и обновляет страницу каждый раз, когда происходит сохранение файла просмотра. По умолчанию Vite обновляет страницу при каждом изменении файлов в этих папках:

  • app/View/Components/
  • lang/
  • resources/views/
  • routes/
Когда есть конфигурация Vite, указывающая на CSS и JavaScript файлы, мы можем ссылаться на эти файлы, используя @vite
@vite(['resources/css/app.css', 'resources/js/app.js'])

2 .1 .2 Vite для Vue

Сперва ставим Vite

npm install --save-dev @vitejs/plugin-vue
Кофигурационный файл vite.config.js пример:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
  plugins: [
    laravel(['resources/js/app.js']),
      vue({
        template: {
          transformAssetUrls: {
          base: null,
          includeAbsolute: false,
        },
      },
    }),
  ],
});

2 .1 .3 Vite для React

Установка:
npm install --save-dev @vitejs/plugin-react
Конфигурационный файл
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
  plugins: [
    laravel(['resources/js/app.js']),
    react(),
  ],
});

2 .1 .4 Vite для одностраничных приложений

Для одностраничных приложений (SPA), можно удалить resources/css/app.css из файла vite.config.js, который удаляет его как точку входа. Далее необходимо импортировать файлы CSS и JavaScript, добавив эту строку в свой resources/js/app,js, непосредственно под импортом начальной загрузки:
import './bootstrap';
import '../css/app.css';

2 .2 Сборка фронтенда

Сперва необходимо установить модули фронтенда с помощью команды

npm i

Эта команда используется для запуска сценария разработки, определенного в файле package.json проекта. Чтобы узнать, что именно запускается командой, сначала нужно открыть файл package.json.

После чего можно приступать к разработке. Команда

npm run dev

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

Перед тем как выкладывать проект на сервер необходима другая команда

npm run build

Которая и выполнит всю сборку.

Вопросы: Какой командой выполняется сборка фронтенда?

2 .3 AlpineJS

Сперва необходимо установить AlpineJS как зависимость node

npm install alpinejs

После установки, подключим Alpine в файле resources/js/app.js

import Alpine from 'alpinejs'
 
window.Alpine = Alpine
 
Alpine.start()

2 .4 События AlpineJS

Для добавления прослушивателей к тэгу можно использовать атрибут x-on:

 
<button x-on:click="console.log('clicked')">...</button> 
или диррективу @: @change, @click...

2 .5 Livewire

Livewire - это composer-зависимость для Laravel

Установка Livewire:

composer require livewire/livewire

После установки livewire необходимо добавить диррективы @livewireStyles и @livewireScripts в основной базовый шаблон приложения:

 
    ...
    @livewireStyles
 
    ...
    @livewireScripts
 

2 .5 .1 Ручная привязка Livewire и AlpineJS

По умолчанию Alpine и Livewire загружаются с помощью тега <script src="/livewire.js">, то есть нельзя контролировать порядок загрузки этих библиотек. Следовательно, импорт и регистрация плагинов Alpine, как показано в примере ниже, больше не будут работать:

	// Внимание: Этот фрагмент демонстрирует, что НЕ нужно делать...
	import Alpine from 'alpinejs'
	import Clipboard from '@ryangjchandler/alpine-clipboard'
	 
	Alpine.plugin(Clipboard)
	Alpine.start()

Для решения этой проблемы необходимо сообщить Livewire, что в дальнейшем будет использоваться версия модуля ESM (ECMAScript), и предотвратить внедрение тега <script src="/livewire.js">. Для этого необходимо добавить директиву @livewireScriptConfig в файл макета (resources/views/components/layouts/app.blade.php):

@livewireScriptConfig 

Когда Livewire обнаружит директиву @livewireScriptConfig, то воздержится от внедрения скриптов Livewire и Alpine. Если вы используете директиву @livewireScripts для ручной загрузки Livewire, обязательно удалите ее. Обязательно добавьте директиву @livewireStyles, если она еще не присутствует.

Последний шаг - импорт Alpine и Livewire в наш файл app.js, позволяющий зарегистрировать любые пользовательские ресурсы, и, наконец, запуск Livewire и Alpine:

import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
	import Clipboard from '@ryangjchandler/alpine-clipboard'
	 
	Alpine.plugin(Clipboard)
	 
	Livewire.start()

2 .5 .2 CKEditor для textarea

Подключить CKEditor можно в тэг script с помощью CDN:

https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js

Чтобы создать экземпляр классического редактора, используйте статический метод ClassicEditor.create(). Вот пример с подключением редактора, javascript:

 ClassicEditor
   .create(document.querySelector('#message'));

Особенности в Livewire

1. Livewire обновляет страницу с автоматической очисткой всех данных форм, а данные данного редактора необходимо сохранить. Поэтому необходимо textarea поместить в div, с атрибутом wire:ignore, тогда livewire не будет обновляеть содержимое этого тега:

2. Компоненты Livewire хранят и отслеживают данные как общедоступные свойства класса компонента и поставляются со своими событиями. Вот пример с прослушкой события ввода и связью со свойством класса:

        ClassicEditor
            .create(document.querySelector('#message'))
            .then(editor => {
                editor.model.document.on('change:data', () => {
                @this.set('message', editor.getData())
                    ;
                })
            })
            .catch(error => {
                console.error(error);
            });

3. Liviewire позволяет загрузить данные скрипты только для текущего компонента, где они будут использоваться, не перегружая лишними данными всё приложение. Для этого используем стэки Laravel.

В блэйд-компоненте поместить их в @push('scripts') диррективу. Тогда в классе компонента Livewire при рендеринге шаблона необходимо укзать базовоый шаблон, сделать это можно с пощьюю метода layout.

Пример:

...
return view('livewire.form-news')->layout('layouts.app');
...

В самом базовом шаблоне должна присутствовать директива @stack('scripts').

Выводы

Таким образом мы получили Livewire-компонент со встроенным CKEditor-ом, причём подргузка необходимых скриптов осуществляется только при вызове самого копонента.

3 Продвинутый уровень

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

3 .1 Полнотекстовый поиск Laravel Scout

Laravel Scout предоставляет простое решение на основе драйверов для добавления полнотекстового поиска в модели Eloquent. Используя наблюдатели моделей, Scout автоматически синхронизирует поисковые индексы с записями Eloquent.

https://laravel.com/docs/10.x/scout

Вопросы: Что такое Laravel Scout и как реализовать полнотекстовый поиск в Laravel?

3 .2 Помощник по отладке Laravel Telescope

Laravel Telescope — помощник по отладке фреймворка Laravel. Telescope обеспечивает понимание запросов, поступающих в ваше приложение, исключений, записей журнала, запросов к базе данных, заданий в очереди, почты, уведомлений, операций кэша, запланированных задач, дампов переменных и многого другого. Telescope это  дополнение к  местной среде разработки Laravel.

https://laravel.com/docs/10.x/telescope

Вопросы: Зачем нужен Laravel Telescope?

3 .3 Коллекции Laravel

Коллекции — это мощный способ работы с массивами данных. Коллекции Laravel предоставляют множество методов манипулирования данными.

3 .4 Пларнировщик задач

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

Список задач для планировщика находится в файле App\Console\Kernel.php в методе schedule. По умолчанию он выглядит так.

    protected function schedule(Schedule $schedule): void
    {
        //$schedule->command('inspire')->hourly();
    }

Если мы запустим Artisan команду schedule:list, которая покажет список задач на выполнение, то по увидим ответ No scheduled tasks have been defined. Однако после раскоментирования команды $schedule->command('inspire')->hourly();, увидим уже другой ответ, который говорит о том, что скоро задача выполнится.

Обычно время, или промежуток времени, через которые будут запускаться задачи определяется сервером. Но у Laravel есть также возможность запускать такие задачи локально.

Для того чтобы локально, на своём компьютере запустить задачи планировщика на выполнения, необходимо вызвать Artisan-команду schedule:work.

php artisan schedule:work

Эта команда будет выполняться на переднем плане и вызывать планировщик.

Вопросы: Для чего нужен планировщик задач и как его запустить локально?

3 .5 Продвинутые компоненты Laravel Livewire

Laravel Livewire — это полнофункциональная платформа для создания динамических веб-интерфейсов. Livewire сочетает в себе лучшее от Laravel и Vue.js для упрощения разработки интерфейса компонентов. По сути, Livewire - это продвинутый компонент vue, за которым стотит класс laravel.

Вопросы: Что такое Livewire? С помощью какой Artisan-команды можно создать компонент Livewire?

3 .6 Policies и gates

Policies и gates это механизмы авторизации в Laravel, которые позволяют вам определять и проверять права пользователей на определенные действия.

Policies это классы, которые организут логику авторизации вокруг определённой модели или ресурса. К примеру, имеется модель App\Models\Post и App\Policies\PostPolicy для авторизации действий пользователя, таких как создание или обновление сообщений.

Вы можете создать политику с помощью make:policy Artisan-команды. Созданный класс появится в дирректории app/Policies, которая будет создана, если команда вызывается впервые. Имеется также возможность при создании Policy привязывать их к модели:

php artisan make:policy PostPolicy --model=Post

Gates — это просто замыкания, которые определяют, имеет ли пользователь право выполнить данное действие. Обычно gate определяется в методе загрузки класса App\Providers\AuthServiceProvider с использованием фасада Gate. Класс gate всегда получает экземпляр пользователя в качестве первого аргумента и может опционально получать дополнительные аргументы, такие как соответствующая модель Eloquent. Может быть использован, чтобы определить, может ли пользователь обновить данную модель. Gate выполнит это, сравнивая идентификатор пользователя с user_id пользователя, создавшего сообщение.

Вопросы: Для чего нужны Policy и как их создать? Для чего нужны gates? Для чего нужен пакет Laravel Passport?

3 .7 QraphQL vs EloquentFilter

GraphQL

GraphQL позволяет запрашивать и получать только те данные, которые нужны фронтенду, сокращая избыточную и недостаточную выборку. Вы можете реализовать GraphQL в Laravel, используя такие пакеты, как Lighthouse.

EloquentFilter

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

http://tucker-eric.github.io/EloquentFilter/

3 .8 Pasport или Sanctum

Прежде чем начать, необходимо определить, будет ли приложение обслуживаться Laravel Passport или Laravel Sanctum. Если приложению необходима поддержка OAuth2, следует использовать Laravel Passport.

Однако, если вы пытаетесь аутентифицировать одностраничное приложение, мобильное приложение или выдать токены API, вам следует использовать Laravel Sanctum. Laravel Sanctum не поддерживает OAuth2; но обеспечивает гораздо более простой процесс разработки аутентификации API.

Sanctum - это пакет, созданный и поддерживаемый основной командой Laravel, который можно использовать для аутентификации по API-токену или SPA (одностраничное приложение) или даже для мобильных приложений. Решаемые задачи: выпуск токена, его аутентификацию и авторизацию.

Вопросы: Для чего нужен пакет Passport? Что такое sanctum? Объясните для чего нужен пакет Laravel Sanctum?

3 .9 Стэк Tall

Стэк разработки Tall - это перспективный стэк разработки веб приложений, включает в себя

  • Tailwind
  • Alpine
  • Laravel
  • Livewire

С самим стэком можно ознакомиться по адресу https://tallstack.dev/

Важно отметить, что стэк Tall предназначен не только для создания приложений в соответствии с архитектурой MVC (по умолчанию это все laravel-приложения), но может быть использован и в архитекутре MV-VM (это компонентная разработка, которая легко реализуется данным стэком). Вот несколько модулей, предоставляющих готовое решение по стэку.

Genesis - https://github.com/thedevdojo/genesis

Genesis это Laravel Starter Kit содержащий готовое решение с использованием стэка TALL, содержит: TailwindCSS, AlpineJS, Laravel, Livewire, а также Volt и Folio файлы. Ещё включает в себя Authentication, User Dashboard, Edit Profile, и набор UI Components.

Splade - https://splade.dev/docs/ssr

Splade - это еще один StarterKit Server-Side Rendering (SSR) решение с использованием всё того же стэка Tall. Splade предоставляет очень простой способ создания одностраничных приложений (SPA) с использованием стандартных шаблонов Laravel Blade, дополненных компонентами Vue 3 без рендеринга. Данное решение предоставляет возможность создавть страницы, совмещая простоту Blade с возможностями SSR.

 

Вопросы: Расшифруйте понятия стэка Tall

3 .10 Кэш

Для оптимизации производительности приложения необходимо

- настроить систему кэширования,

- оптимизировать запросы к базе данных,

- произвести балансировку нагрузки, масштабирование серверов и использование сетей доставки контента (CDN).

Система кэширования в Laravel настроена по умолчанию. Как правило, изменений она не требут. Но часто приходится обнулять кэш, например для обновления конфигов, маршрутов, сессий и т.д. Для этого имеется специальная Artisan-команда

php artisan optimize

или

php artisan optimize:clear
Вопросы: Как обнулить кэш? Каковы наиболее распространенные методы оптимизации производительности приложений Laravel с высоким трафиком?

3 .11 Трансляция событий, broadcasting

Трансляция событий в Laravel позволяет транслировать события во внешние среды JavaScript, такие как Vue.js или React, что позволяет обновлять приложения в реальном времени.

Механизм транляции событий строится на основе WebSockets, которые используются для реализации пользовательских интерфейсов, обновляемых в режиме реального времени. Когда на сервере обновляются некоторые данные, сообщение отправляется через соединение WebSocket для обработки клиентом. WebSockets предоставляют более эффективную альтернативу постоянному опросу сервера приложения на наличие изменений данных, которые должны быть отражены в пользовательском интерфейсе.

Например. Как только данные получены, сервер может ответить клиенту сообщением о том, что получены новые данные и может вывести эти данные, без необходимости обновлять страницу.

Чтобы помочь в создании функций такого типа, Laravel позволяет легко «транслировать» события на стороне сервера через соединение WebSocket. Трансляция событий Laravel позволяет вам использовать одни и те же имена событий и данные между серверным приложением Laravel и клиентским приложением JavaScript.

Laravel Echo

Laravel Echo это библиотека JavaScript, задача которой подписка на каналы и прослушка событий Laravel. Работает с множеством broadcasting-драйверов, такими как Pusher

Подробнее в официальной документации Laravel https://laravel.com/docs/10.x/broadcasting#introduction

Вопросы: Объясните концепцию трансляции событий в Laravel. Что такое Laravel Echo?

3 .12 Очереди

Очереди queues

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

В файле конфигурации config/queue.php есть массив конфигурации соединений. Этот параметр определяет подключения к серверным службам очередей, таким как Amazon SQS, Beanstalk или Redis. Однако любое соединение с очередью может иметь несколько «очередей», которые можно рассматривать как разные стопки или стопки заданий, поставленных в очередь.

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

use App\Jobs\ProcessPodcast;
 
// This job is sent to the default connection's default queue...
ProcessPodcast::dispatch();
 
// This job is sent to the default connection's "emails" queue...
ProcessPodcast::dispatch()->onQueue('emails');
По умолчанию все поставленные в очередь задания приложения хранятся в каталоге app/Jobs. Если каталог не существует, он будет создан при запуске Artisan-команды make:job:
php artisan make:job ProcessPodcast
После того как вы написали класс задания, вы можете отправить его, используя метод диспетчеризации самого задания. Аргументы, переданные методу диспетчеризации, будут переданы конструктору задания:
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Jobs\ProcessPodcast;
use App\Models\Podcast;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
 
class PodcastController extends Controller
{
    /**
     * Store a new podcast.
     */
    public function store(Request $request): RedirectResponse
    {
        $podcast = Podcast::create(/* ... */);
 
        // ...
 
        ProcessPodcast::dispatch($podcast);
 
        return redirect('/podcasts');
    }
}

Laravel включает команду Artisan, которая запускает обработчик очереди и обрабатывает новые задания по мере их помещения в очередь. Запустить этот процесс можно с помощью Artisan-команды queue:work. Обратите внимание, что после запуска команды queue:work она будет продолжать выполняться до тех пор, пока не будет остановлена вручную или пока вы не закроете терминал:

php artisan queue:work

Laravel предлагает Horizon, красивую панель мониторинга и систему настройки для очередей на базе Redis. Подробнее в официальной документации Laravel Horizon.

Вопросы: Для чего нужны очереди в Laravel? Что такое Laravel Horizon?

3 .13 Обработка исключений

Что такое исключения в Laravel

Исключения — это ошибки, возникающие во время выполнения программы и нарушающие нормальный поток управления.

В процессе разработки может возникнуть необходимость генерировать/выбросить исключение вручную, в коде приложения, т.е. указать, что что-то пошло не так или что какое-то условие не было выполнено. Например, нет такой страницы, или пользователь не авторизован, попытка доступа к несуществующему свойству объекта, деление на ноль или вызов функции с недопустимыми аргументами — это всё примеры исключений.

Исключения могут создавать сами механизмы PHP (например, ParseError или TypeError) или кодом приложения (например, InvalidArgumentException или ModelNotFoundException). Исключение также могут быть определены пользователем путём расширения базового класса Exception или любого из его подклассов.

Как Laravel обрабатывает исключения

В новом проекте Laravel, обработка ошибок и исключений уже настроена. В классе App\Exceptions\Handler все исключения, создаваемые приложением, регистрируются, а затем отображаются для пользователя.

По умолчанию Laravel преобразует все исключения в HTTP ответы с соответствующими кодами состояния и сообщениями об ошибках. Например, исключение 404 Not Found приведёт к HTTP-ответу с кодом состояния 404 и сообщением Not Found. Исключение 500 Internal Server Error приведёт к HTTP-ответу с кодом состояния 500 и сообщением Whoops, something went wrong.

Laravel также предоставляет удобный способ отображения пользовательских страниц ошибок для разных кодов состояния HTTP. Например, чтобы настроить страницу ошибки 404, необходимо создать файл resources/views/errors/404.blade.php.

Как выбрасывать исключения в Laravel

Чтобы выбросить исключение в Laravel, можно использовать ключевое слово throw, за которым следует экземпляр класса исключения. Например:

public function show($id)
{
    $post = Post::find($id);

    if ($post == null) {
        // Выбросить исключение, если статья не существует
        throw new ModelNotFoundException('Post not found');
    }

    if (Auth::user()->cannot('view', $post)) {
        // Выбросить исключение, если пользователь не авторизован для просмотра статьи
        throw new AuthorizationException('You are not allowed to view this post');
    }

    return view('posts.show', compact('post'));
}

Также имеется возможность использовать хелпер abort() для выбрасывания исключения, чтобы создать исключение с заданным кодом HTTP состояния и дополнительным сообщением. Например:

public function update(Request $request, $id)
{
    $post = Post::find($id);

    if ($post == null) {
        // Прервать с кодом состояния 404 и пользовательским сообщением
        abort(404, 'Post not found');
    }

    if (Auth::user()->cannot('update', $post)) {
        // Прервать с кодом состояния 403 и сообщением по умолчанию
        abort(403);
    }

    // Обновить статью ...
}

На практике часто используется метод abort_if(), тогда условие, код ошибки и само сообщение вмещается в одну строку:

abort_if(! Auth::user()->isAdmin(), 403);

3 .14 Swoole для PHP

По сравнению с другими платформами или программным обеспечением асинхронного программирования, такими как Nginx, Tornado, Node.js, Open Swoole представляет собой полноценное асинхронное решение PHP со встроенной поддержкой асинхронного программирования через сопрограммы, ряд модулей многопоточного ввода-вывода (HTTP). Server, WebSockets, TaskWorkers, пулы процессов) и поддержку популярных клиентов PHP, таких как PDO для MySQL, Redis и CURL.

Благодаря мощности и производительности Open Swoole вы можете писать масштабируемые PHP-приложения для веб-серверов, серверных API, игровых серверов, чат-систем, платформ CMS, микросервисов, веб-сервисов реального времени и т. д.

3 .15 Процесс непрерывной разработки

Лучшие практики включают в приложение написание модульных и интеграционных тестов, настройку конвейеров автоматического тестирования и использование инструментов CI/CD, таких как GitLab CI. В часности, создание веток "develop" и "production" и серверов под каждую ветку.

На гите, вместо неконтроллируемого роста веток (такое наблюдается когда под каждую задачу создаётся ветка) следует использовать фичи гита (features).

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

Вопросы: Опишите процесс непрерывной интеграции в Laravel?

Заключение

Список использованных источников

1. [url] Официальная документация Laravel http://laravel.com

Приложения