Наименование Разработка веб-приложений
Автор А.В.Михалькевич
Специальность Разработка веб-приложения с помощью стэка TALL: TailwindCSS, AlpineJS, Laravel и Livewire,
Анотация
Теория и практика веб-разработки.
Anotation in English
Theory and practice of web development.
Ключевые слова web, laravel, web-development, web-creator, site
Количество символов 69943
Начинаем разработку с изучения основных технологий и выбранной архитектуры веб-приложерия.
MVC означает Модель-Представление-Контроллер.
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
Определить маршруты приложения можно в файле 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
. Это гарантирует, что входящий запрос соответствует правильному маршруту.
База данных
Базу данных необходимо создать. Сделать это можно с помощью PHPMyAdmin или любым другим способом. Лучше, если у проекта будет одна база данных, но Laravel может подключаться к множествам баз. Важно помнить, что программист взаимодействует с моделями данных, или посредством моделей с таблицами баз данных.
В частности, Laravel поддерживает четыре базы данных:
Подключение к базе данных осуществляется в корневом файле .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"; }
Для проведения теста иногда приходится заполнить базу данных, причём данные должны выглядеть более-менее как настоящие, а не просто набором букв. Данные можно вводить и в ручную, но это пойдёт, пока их мало. А в противном случае лучше воспользоваться специальным инструментом для заполнения тест данными — фабрикой моделей.
Хоть и при помощи сидов можно создать несколько записей, но фабрика моделей генерирует множество.
Файлы фабрик моделей хранятся в папке 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();
Связи моделей
Eloquent предлагает встроенный механизм связывания моделей. Вот поддерживаемые типы связей:
Для реализации связи модели с другой моделью, необходимо создать метод, возвращающий нужный тип связи. Пример связи: Каталог содержит множество продуктов:
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 связывает две необходимые модели через промежуточную таблицу, для которой даже нет необходимости создавать модель.
Представления, 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 - шаблонизатор, который сокращет код, разбивает представление на элементы и представляет возможность повторного использования элементов шаблона.
Middleware или промежуточное программное обеспечение — это фильтр HTTP-запросов.
Он позволяет вам выполнять действия до или после того, как запрос попадет в приложение, например аутентификацию и ведение журнала. Как следует из названия, промежуточное программное обеспечение работает как посредник между запросом и ответом.
Например, Laravel состоит из промежуточного программного обеспечения, которое проверяет, аутентифицирован ли пользователь приложения или нет. Если пользователь прошел аутентификацию и пытается получить доступ к панели мониторинга, промежуточное программное обеспечение перенаправит этого пользователя на домашнюю страницу; в противном случае пользователь будет перенаправлен на страницу входа.
В Laravel доступно два типа промежуточного программного обеспечения:
php artisan make:middlewareUserMiddleware
Миграции
Миграции — это способ управления структурами таблиц базы данных и внесения в нее изменений с течением времени.
Вы можете создавать и запускать миграции с помощью команд 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(); });
Самое простое решение для валидации использовать метод 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()
Service providers или Поставщики услуг — это способ загрузки и регистрации сервисов в сервисном контейнере Laravel. Они помогают управлять зависимостями и настраивать различные компоненты приложения. Рассмотрим artisan команду, которую можно использовать для создания поставщика услуг:
php artisan make:provider ClientsServiceProvider
Классы поставщиков услуг extend Illuminate\Support\ServiceProviderclass. Класс поставщика услуг содержит два основных метода
В методе register() следует привязывать элементы только к сервисному контейнеру.
Зарегистрировать какие-либо прослушиватели событий, маршруты или любую другую функциональность пишем в методе boot().
Первоначальные данные, seeders используются для заполнения таблиц базы реальными данными. Создавать и запускать на выполнение можем с помощью Artisan. Процесс работы с сидерами таков:
1. создать сидер:
php artisan make:seeder CatalogSeeder
2. заполнить данными.
3. запустить на выполнение:
php artisan db:seed
Laravel Container — мощный инструмент для управления зависимостями и хранения объектов для различных целей.
Внедрение зависимостей обычно используется в Laravel. Даже доступ к Request мы в основном внедряем.
public function __construct (Request $ request)
Для защиты форм от межсайтовых подделок запросов (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', ]; }
Продолжаем разработку, подключая фронтенд
Vite - это локальная среда разработки фронтенд-приложений.
В Laravel он в основном используется для объединения ресурсов CSS и JavaScript. Laravel предлагает плагин NPM и директиву Blade. Оба они включены в приложения Laravel «из коробки», и поставляются с файлом конфигурации: vite.config.js
.
Так выглядит 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 обновляет страницу при каждом изменении файлов в этих папках:
@vite
@vite(['resources/css/app.css', 'resources/js/app.js'])
Сперва ставим 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, }, }, }), ], });
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(), ], });
import './bootstrap'; import '../css/app.css';
Сперва необходимо установить модули фронтенда с помощью команды
npm i
Эта команда используется для запуска сценария разработки, определенного в файле package.json проекта. Чтобы узнать, что именно запускается командой, сначала нужно открыть файл package.json.
После чего можно приступать к разработке. Команда
npm run dev
используется в процессе разработки приложения. Это общая команда npm, которую можно найти во многих современных фрэймворках? После запуска этой команды, laravel начинает прослушку изменений кода в файлах приложения. И браузер автоматически в нужный момент производит обновление страниц. Однако эта команда полезна только в процессе разработки приложения.
Перед тем как выкладывать проект на сервер необходима другая команда
npm run build
Которая и выполнит всю сборку.
Сперва необходимо установить AlpineJS как зависимость node
npm install alpinejs
После установки, подключим Alpine в файле resources/js/app.js
import Alpine from 'alpinejs' window.Alpine = Alpine Alpine.start()
Для добавления прослушивателей к тэгу можно использовать атрибут x-on
:
<button x-on:click="console.log('clicked')">...</button>или диррективу
@
: @change
, @click
...
Livewire - это composer-зависимость для Laravel
Установка Livewire:
composer require livewire/livewire
После установки livewire необходимо добавить диррективы @livewireStyles
и @livewireScripts
в основной базовый шаблон приложения:
... @livewireStyles ... @livewireScripts
По умолчанию 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()
Подключить CKEditor можно в тэг script с помощью CDN:
https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js
Чтобы создать экземпляр классического редактора, используйте статический метод ClassicEditor.create(). Вот пример с подключением редактора, javascript:
ClassicEditor .create(document.querySelector('#message'));
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-ом, причём подргузка необходимых скриптов осуществляется только при вызове самого копонента.
Переносим разработку веб-приложения на продвинутый уровень.
Laravel Scout предоставляет простое решение на основе драйверов для добавления полнотекстового поиска в модели Eloquent. Используя наблюдатели моделей, Scout автоматически синхронизирует поисковые индексы с записями Eloquent.
https://laravel.com/docs/10.x/scout
Laravel Telescope — помощник по отладке фреймворка Laravel. Telescope обеспечивает понимание запросов, поступающих в ваше приложение, исключений, записей журнала, запросов к базе данных, заданий в очереди, почты, уведомлений, операций кэша, запланированных задач, дампов переменных и многого другого. Telescope это дополнение к местной среде разработки Laravel.
https://laravel.com/docs/10.x/telescope
Коллекции — это мощный способ работы с массивами данных. Коллекции Laravel предоставляют множество методов манипулирования данными.
Планировщик задач 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
Эта команда будет выполняться на переднем плане и вызывать планировщик.
Laravel Livewire — это полнофункциональная платформа для создания динамических веб-интерфейсов. Livewire сочетает в себе лучшее от Laravel и Vue.js для упрощения разработки интерфейса компонентов. По сути, Livewire - это продвинутый компонент vue, за которым стотит класс laravel.
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 пользователя, создавшего сообщение.
GraphQL
GraphQL позволяет запрашивать и получать только те данные, которые нужны фронтенду, сокращая избыточную и недостаточную выборку. Вы можете реализовать GraphQL в Laravel, используя такие пакеты, как Lighthouse.
EloquentFilter
Почти той же гибкости в запросах можно добиться и с помощью пакета EloquentFilter. Существенная разница в том, что вместо создания целой системы сервер-клиентского приложения (как в GraphQL), все необходимые для фильтрации и поиска методы привязываются к модели.
http://tucker-eric.github.io/EloquentFilter/
Прежде чем начать, необходимо определить, будет ли приложение обслуживаться Laravel Passport или Laravel Sanctum. Если приложению необходима поддержка OAuth2, следует использовать Laravel Passport.
Однако, если вы пытаетесь аутентифицировать одностраничное приложение, мобильное приложение или выдать токены API, вам следует использовать Laravel Sanctum. Laravel Sanctum не поддерживает OAuth2; но обеспечивает гораздо более простой процесс разработки аутентификации API.
Sanctum - это пакет, созданный и поддерживаемый основной командой Laravel, который можно использовать для аутентификации по API-токену или SPA (одностраничное приложение) или даже для мобильных приложений. Решаемые задачи: выпуск токена, его аутентификацию и авторизацию.
Стэк разработки Tall - это перспективный стэк разработки веб приложений, включает в себя
С самим стэком можно ознакомиться по адресу 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.
Для оптимизации производительности приложения необходимо
- настроить систему кэширования,
- оптимизировать запросы к базе данных,
- произвести балансировку нагрузки, масштабирование серверов и использование сетей доставки контента (CDN).
Система кэширования в Laravel настроена по умолчанию. Как правило, изменений она не требут. Но часто приходится обнулять кэш, например для обновления конфигов, маршрутов, сессий и т.д. Для этого имеется специальная Artisan-команда
php artisan optimize
или
php artisan optimize:clear
Трансляция событий в 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
При создании веб-приложения у часто возникают такие задачи, выполнение которых занимает слишком много времени, такие как анализ и сохранение загруженного файла 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.
Исключения — это ошибки, возникающие во время выполнения программы и нарушающие нормальный поток управления.
В процессе разработки может возникнуть необходимость генерировать/выбросить исключение вручную, в коде приложения, т.е. указать, что что-то пошло не так или что какое-то условие не было выполнено. Например, нет такой страницы, или пользователь не авторизован, попытка доступа к несуществующему свойству объекта, деление на ноль или вызов функции с недопустимыми аргументами — это всё примеры исключений.
Исключения могут создавать сами механизмы PHP (например, ParseError
или TypeError
) или кодом приложения (например, InvalidArgumentException
или ModelNotFoundException
). Исключение также могут быть определены пользователем путём расширения базового класса Exception
или любого из его подклассов.
В новом проекте 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, можно использовать ключевое слово 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);
По сравнению с другими платформами или программным обеспечением асинхронного программирования, такими как Nginx, Tornado, Node.js, Open Swoole представляет собой полноценное асинхронное решение PHP со встроенной поддержкой асинхронного программирования через сопрограммы, ряд модулей многопоточного ввода-вывода (HTTP). Server, WebSockets, TaskWorkers, пулы процессов) и поддержку популярных клиентов PHP, таких как PDO для MySQL, Redis и CURL.
Благодаря мощности и производительности Open Swoole вы можете писать масштабируемые PHP-приложения для веб-серверов, серверных API, игровых серверов, чат-систем, платформ CMS, микросервисов, веб-сервисов реального времени и т. д.
Лучшие практики включают в приложение написание модульных и интеграционных тестов, настройку конвейеров автоматического тестирования и использование инструментов CI/CD, таких как GitLab CI. В часности, создание веток "develop" и "production" и серверов под каждую ветку.
На гите, вместо неконтроллируемого роста веток (такое наблюдается когда под каждую задачу создаётся ветка) следует использовать фичи гита (features).
Это позволит вести бесконечную разработку приложения без ущерба работающей копии приложения на ветке production. Процесс непрерывной разработки включает в себя разработку приложения на ветке develop, тестирование этой ветки на отдельном сервере, и заливку после тестирования на ветку production.