Установка — composer create-project —prefer-dist laravel/laravel laravelblog
Что было сделано:
Развернул ларавел, тут есть в папке routes файл web.php и в нем роуты описываются так
Route::get('/admin', \App\Http\Controllers\AdminController::class);
Route::get('/', function () {
return view('welcome');
});
Route::get('/', \App\Http\Controllers\Main\IndexController::class);
Т.е. по сути либо мы вставляем вторым параметром функцию, либо указываем на контроллер,
где «\App\Http\Controllers\Main\» путь к папке корнтролеру, а в нем есть файл — IndexController, внутри которого такой код:
<?php
namespace App\Http\Controllers\Main;
use App\Http\Controllers\Controller;
class IndexController extends Controller
{
public function __invoke()
{
return view(view:'main.index');
}
}
где мы создаем класс, наpвание которого = название файла и внутри вызываем view —
‘return view(view:’main.index’);’
Которое находится в resources/views/main/ и там файл index.blade.php
Затем мы создали папку в views — layouts, которое содержит шапку и футер сайта (то что подключается на всех страницах)
В папке создали — main.blade.php , и в нем, там где вставляется разный контент страниц вызвали функцию
<div class="content-wrapper">
@yield('content')
<!-- /.content -->
</div>
View, которую вызывает контролер, мы добавили функции шаблонизатора:
@extends('layouts.main')
@section('content')
тут то что должно отобразиться
@endsection
Структура папок

###################################
{{now()}} — хелпер показывает дату текущую
{{now()->year}} — хелпер показывает год
CRUD
Создаем миграцию и модель
php artisan make:model Category -m — -m чтобы создалась автоматом миграция

Файл миграции:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('title'); - так можно задавать поля для создания в бд
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categories');
}
};
Затем чтобы как я понял данный файл сделал в бд записи, надо выполнить
php artisan migrate
Видим, что выполнилось:

Затем мы делаем стандартные вещи типа в созданной модели категории пишем код:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $table = 'categories';
protected $guarded = false; - говорят обязательно
}
6 видео, 2мин
Чел создает какие то инвокбл контроллер,
php artisan make:controller Category/IndexController
Таким образом нафигачил еще кучу контроллеров под любое действие

Причем, внутри контроллеров, сделал 1 функцию invoke как я понял, когда вы контроллере 1 функция, то единственную функцию так называют
<?php
namespace App\Http\Controllers\Category;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class CreateController extends Controller
{
public function __invoke(){
}
}
Создал кучу роутов для категорий, через группу роутов
Route::group(['prefix'=>'categories'],function(){
Route::get('/', \App\Http\Controllers\Category\IndexController::class)->name('category.index');
Route::get('/create', \App\Http\Controllers\Category\CreateController::class)->name('category.create');
Route::post('/', \App\Http\Controllers\Category\StoreController::class)->name('category.store');
Route::get('/{category}/edit', \App\Http\Controllers\Category\EditController::class)->name('category.edit');
Route::get('/{category}', \App\Http\Controllers\Category\ShowController::class)->name('category.show');
Route::patch('/{category}', \App\Http\Controllers\Category\UpdateController::class)->name('category.update');
Route::delete('/{category}', \App\Http\Controllers\Category\DeleteController::class)->name('category.delete');
});
Затем сделали view для страниц категорий, взяв дизайн из main

Создаем какие то реквесты:
php artisan make:request Category/StoreRequest, как я понял потому что стор через реквест работает

ПРичем сделали такие правки в обоих файлах реквестов
<?php
namespace App\Http\Requests\Category;
use Illuminate\Foundation\Http\FormRequest;
class UpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true; - тут
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'title'=>'required|string' - тут
];
}
}
Нужно почитать зачем они и что делает public function authorize(): bool
indexController
<?php
namespace App\Http\Controllers\Category;
use App\Http\Controllers\Controller;
use App\Models\Category;
use Illuminate\Http\Request;
class IndexController extends Controller
{
public function __invoke()
{
$categories = Category::all();
return view('category.index',compact('categories'));
}
}
$categories = Category::all(); — магически получает все категории, и затем как то используем compact
<?php
namespace App\Http\Controllers\Category;
use App\Http\Controllers\Controller;
use App\Http\Requests\Category\StoreRequest;
use App\Models\Category;
use Illuminate\Http\Request;
class StoreController extends Controller
{
public function __invoke(StoreRequest $request){
$data= $request->validated();
Category::firstOrCreate($data);
return redirect()->route('category.index');
}
}
Обрати внимание на лаконичный редирект по имени роута
Как я понял, то что мы передали в компакт в контроллере, становится доступным во вью, например в инщдексном категории мы отображаем категории так
@foreach ($categories as $category)
<tr>
<td>{{$category->id}}</td>
<td>{{$category->title}}</td>
</tr>
@endforeach
А вот и для чего реквесты, например форму мы отправляем через роут на реквест файл
<form action="{{route('category.store')}}" method="POST"></form>
12 56 6 урок
КАк в итоге сделали круд на категорию:
Route::group(['prefix'=>'categories'],function(){
Route::get('/create', \App\Http\Controllers\Category\CreateController::class)->name('category.create');
Route::post('/', \App\Http\Controllers\Category\StoreController::class)->name('category.store');
});
Затем есть форма во вьювз, которая отвечает за создание категории
<form action="{{route('category.store')}}" method="POST">
@csrf - валидация какая то
<div class="form-group">
<input type="text" name="title" class="form-control" placeholder="Наименование">
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Добавить">
</div>
</form>
Видим что форма отправиться на роут — category.store, который ведет на контроллер —
App\Http\Controllers\Category\StoreController
Внутри данного контроллера
<?php
namespace App\Http\Controllers\Category;
use App\Http\Controllers\Controller;
use App\Http\Requests\Category\StoreRequest; //- импортируется реквест
use App\Models\Category;
use Illuminate\Http\Request;
class StoreController extends Controller
{
public function __invoke(StoreRequest $request){
$data= $request->validated();
Category::firstOrCreate($data);
return redirect()->route('category.index');
}
}
Сам реквест
<?php
namespace App\Http\Requests\Category;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'title'=>'required|string'
];
}
}