composer create-project laravel/laravel example-appcd example-app
php artisan servephp artisan make:controller MyFirstControllerphp artisan listГлава 1. Прогулки по пути запроса
require__DIR__.'/../vendor/autoload.php';$app = require_once__DIR__.'/../bootstrap/app.php';$app = require_once__DIR__.'/../bootstrap/app.php';$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);$response = $kernel->handle(
$request = Request::capture()
)->send();$request = Request::capture()$kernel->handlepublicfunctionhandle($request)
{
try {
$request->enableHttpMethodParameterOverride();
$response = $this->sendRequestThroughRouter($request);
} catch (Throwable$e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
}
$this->app['events']->dispatch(
newRequestHandled($request, $response)
);
return$response;
}$response = $this->sendRequestThroughRouter($request);protectedfunctionsendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap();
return (newPipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}return (newPipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}###Глава 2. Middleware
publicfunctionhandle($request, Closure$next)
{
//return$next($request);
}return$next($request);publicfunctionhandle($request, Closure$next)
{
if ($request->ip() !== ‘190.90.90.90’) {
abort(404); }
return$next($request);
}protected$middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];protected$middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];###Глава 3. Route
publicfunctiondispatchToRoute(Request$request)
{
return$this->runRoute($request, $this->findRoute($request));
}publicfunctionboot()
{
$this->routes(function () {
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],Route::get('/', function () {
returnview('welcome');
});###Глава 4. Структура
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=###Глава 5. Конвенция наименований
Глава 6. Миграции
php artisan make:model User -mphp artisan make:migration create_users_table<?phpuseIlluminate\Database\Migrations\Migration;
useIlluminate\Database\Schema\Blueprint;
useIlluminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/** * Run the migrations. * * @return void */publicfunctionup()
{
Schema::create('users', function (Blueprint$table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/** * Reverse the migrations. * * @return void */publicfunctiondown()
{
Schema::dropIfExists('users');
}
}<?phpuseIlluminate\Database\Migrations\Migration;
useIlluminate\Database\Schema\Blueprint;
useIlluminate\Support\Facades\Schema;
returnnewclassextends Migration
{
/** * Run the migrations. * * @return void */publicfunctionup()
{
Schema::table('news', function (Blueprint$table) {
$table->boolean('active')->default(true);
});
}
/** * Reverse the migrations. * * @return void */publicfunctiondown()
{
Schema::table('news', function (Blueprint$table) {
$table->dropColumn('active')
});
}
};php artisan migrate php artisan migrate:rollback php artisan migrate:rollback –step=2Глава 7. Модели
<?phpnamespaceApp\Models;
useIlluminate\Database\Eloquent\Model;
class Service extends Model
{
}<?phpnamespaceApp\Models;
useIlluminate\Database\Eloquent\Model;
class Service extends Model
{
protected$table = ‘custom_table’;
}class Service extends Model
{
protected$fillable = [
'title',
'code'
];
}$user->create(request()->all());Глава 7.1. QueryBuilder
$users = User::query()->where(‘active’, true)->where(‘banned’, false)SELECT * FROM users WHERE active = 1AND banned = 0;$user = User::query()->where(‘active’, true)->where(‘banned’, false)->first()$users = User::query()->where(‘active’, true)->where(‘banned’, false)->get()Глава 7.2. Collections
$users->sortBy(‘name’)->filter(fn($user) => $user->id > 1)Глава 8. Отношения
php artisan make:model Phone<?phpnamespaceApp\Models;
useIlluminate\Database\Eloquent\Model;
class Phone extends Model
{
publicfunctionuser()
{
return$this->belongsTo(User::class);
}
}return$this->belongsTo(User::class, 'foreign_key', 'owner_key');return$this->belongsTo(User::class, 'telefon_uuid', 'uuid');$phone->user->value$phone->user_id = 1; $phone->save();$user = User::find(1);
$phone->user()->associate($user);
$phone->save();$phone->user()->save(newUser([name => ‘CutCode’]))$phone->user()->create([‘name’ => ‘CutCode’])$phone->user()->saveMany([
newUser([‘name’ => ‘CutCode’]),
newUser([‘name’ => ‘Ivan’])
])$phone->user()->createMany([
[name => ‘CutCode’],
[name => ‘Ivan’]
])$phone->user()->update([‘name’ => ‘Oleg’])$phone->user()->save($user)$phone->user()->delete()8.2. HasMany - отношение “Один ко многим”
publicfunctioncomments()
{
return$this->hasMany(Comment::class);
}publicfunctionpost()
{
return$this->belongsTo(Post::class);
}<?phpnamespaceApp\Models;
useIlluminate\Database\Eloquent\Model;
class User extends Model
{
publicfunctionphone()
{
return$this->hasOne(Phone::class);
}
}$user->phone->valuepublicfunctioncomments()
{
return$this->hasMany(Comment::class);
}
publicfunctioncomment()
{
return$this->hasOne(Comment::class);
}SELECT * FROM comments WHERE post_id = 1;SELECT * FROM comments WHERE post_id = 1LIMIT1;8.4. Расширенное использование HasOne
publicfunctionlastComment(): HasOne
{
return$this->hasOne(Comment::class)->latestOfMany();
}publicfunctionfirstComment(): HasOne
{
return$this->hasOne(Comment::class)->oldestOfMany();
}publicfunctionfirstComment(): HasOne
{
return$this->hasOne(Comment::class)->oldestOfMany(‘identity’);
}publicfunctioncurrentPricing()
{
return$this->hasOne(Price::class)->ofMany([
'published_at' => 'max',
'id' => 'max',
], function ($query) {
$query->where('published_at', '<', now());
});
}publicfunctionfirstComment(): HasOne
{
return$this->comments()->one()->oldestOfMany();
}8.5. BelongsToMany - отношение многие ко многим
users
id - integer
name - string
roles
id - integer
name - string
role_user
user_id - integer
role_id - integerSchema::create('role_user', function (Blueprint$table) {
$table->id();
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete()
->cascadeOnUpdate();
$table->foreignId('role_id')
->constrained()
->cascadeOnDelete()
->cascadeOnUpdate();
$table->timestamps();
});publicfunctionroles()
{
return$this->belongsToMany(Role::class);
}Schema::create('product_property', function (Blueprint$table) {
$table->id();
$table->foreignId(‘product_id’)
->constrained()
->cascadeOnDelete()
->cascadeOnUpdate();
$table->foreignId('property_id')
->constrained()
->cascadeOnDelete()
->cascadeOnUpdate();
$table->string(‘value’);
$table->timestamps();
});publicfunctionproperties()
{
return$this->belongsToMany(Property::class)
->withPivot(‘value’);
}foreach ($products->propertiesas$property) {
echo$property->pivot->value;
}$product = Product::find(1);
$products->properties()->attach(1);$products->properties()->attach(1, ['value' => ‘128 mb’]);$product = Product::find(1);
$products->properties()->detach(1);$products->properties()->sync([1,2,3]);$products->properties()->toggle([1, 2, 3]);// начальное состояние
Характеристик товара []
Характеристики айди 1, 10, 20//добавляем характеристику id 10
tovar -> toggle (10)
Характеристик товара [10]
//переключаем характеристику id 10 и добавляем характеристику id 20
tovar -> toggle (10, 20)
Характеристик товара [20]$products->properties()->sync([1 => ['value' => ‘128 mb’], 2, 3]);8.6. HasOneThrough - отношение один к одному через таблицу
mechanics
id - integer
name - string
cars
id - integer
model - string
mechanic_id - integer
owners
id - integer
name - string
car_id - integerclass Mechanic extends Model
{
/** * Get the car's owner. */publicfunctioncarOwner()
{
return$this->hasOneThrough(Owner::class, Car::class);
}
}publicfunctioncarOwner()
{
return$this->hasOneThrough(
Owner::class,
Car::class,
'mechanic_id', // Ключ в таблице cars - связь с текущей таблицей mechanics'car_id', // Ключ в таблице owners связь с таблицей cars через которую мы двигаемся'id', // Primary key в mechanics'id'// Primary key в cars
);
}8.7. HasManyThrough - отношение один ко многим через таблицу
class Mechanic extends Model
{
/** * Get the car's owner. */publicfunctioncarOwners()
{
return$this->hasManyThrough(Owner::class, Car::class);
}
}class Mechanic extends Model
{
publicfunctioncarOwners()
{
return$this->through(‘cars’)->has(‘owners’);
}
}class Mechanic extends Model
{
publicfunctioncars()
{
return$this->hasMany(Car::class);
}
}class Car extends Model
{
publicfunctionowners()
{
return$this->hasMany(Owner::class);
}
}class Car extends Model
{
publicfunctionowner()
{
return$this->hasOne(Owner::class);
}
}class Mechanic extends Model
{
/** * Get the car's owner. */publicfunctioncarOwner()
{
return$this->through(‘cars’)->has(‘owners’);
}
}8.8.Полиморфные отношения
posts
id - integer
title - string
blogs
id - integer
title - string
news
id - integer
title - string
comments
id - integer
text - text
commentable_id - integer
commentable_type - stringclass Post extends Model
{
/** * Get all of the post's comments. */publicfunctioncomments()
{
return$this->morphMany(Comment::class, 'commentable');
}
}class Comment extends Model
{
/** * Get the parent commentable model (post or video). */publicfunctioncommentable()
{
return$this->morphTo();
}
}$post->comments
$blog->comments
$new->commentsposts
id - integer
blogs
id - integer
news
id - integer
images
id - integer
url - string
imageable_id - integer
imageable_type - stringclass Post extends Model
{
/** * Get the post's image. */publicfunctionimage()
{
return$this->morphOne(Image::class, 'imageable');
}
}posts
id - integer
title - string
blogs
id - integer
title - string
news
id - integer
title - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - stringclass Tag extends Model
{
/** * Get all of the posts that are assigned this tag. */publicfunctionposts()
{
return$this->morphedByMany(Post::class, 'taggable');
}
/** * Get all of the videos that are assigned this tag. */publicfunctionblogs()
{
return$this->morphedByMany(Blog::class, 'taggable');
}
}class Post extends Model
{
/** * Get all of the tags for the post. */publicfunctiontags()
{
return$this->morphToMany(Tag::class, 'taggable');
}
}8.9. Eager load
foreach($post->commentsas$comment) {
echo$comment->author->name;
}$comments = Comment::query()->with(‘author’)->get();$post = Post::query()->with(‘comments.author’)->where(‘id’, 1)->first();$post->load(‘comments.author’);8.10. QueryBuilder для отношений
$posts = Post::has('comments')->get();$posts = Post::whereHas('comments', function (Builder$query) {
$query->where('content', 'like', 'code%');
})->get();$posts = Post::whereRelation('comments', 'is_approved', false)->get();8.11. Агрегатные функции для отношений
$posts = Post::withCount('comments')->get();foreach ($postsas$post) {
echo$post->comments_count;
}$posts = Post::withMax('comments', 'likes')->get();
foreach ($postsas$post) {
echo$post->comments_max_likes;
}$posts = Post::withAvg('comments', 'votes')->get();
foreach ($postsas$post) {
echo$post->comments_avg_votes;
}
$posts = Post::withSum('comments', 'votes')->get();
foreach ($postsas$post) {
echo$post->comments_sum_votes;
}9.1. Mutators/Accessors
class User extends Model
{
/** * Get the user's first name. * * @return \Illuminate\Database\Eloquent\Casts\Attribute */protectedfunctionphone(): Attribute
{
return Attribute::make(
get: fn ($value) => ‘+’ . $value,
);
}
}class User extends Model
{
/** * Get the user's first name. * * @return \Illuminate\Database\Eloquent\Casts\Attribute */protectedfunctionname(): Attribute
{
return Attribute::make(
get: fn () => $this->first_name . “ ” . $this->last_name,
);
}
}class User extends Model
{
/** * Get the user's first name. * * @return \Illuminate\Database\Eloquent\Casts\Attribute */protectedfunctionphone(): Attribute
{
return Attribute::make(
set: fn ($value) => trim(preg_replace('/^1|\D/', "", $value)),
);
}
}return Attribute::make(
get: fn ($value) => ‘+’ . $value,
set: fn ($value) => trim(preg_replace('/^1|\D/', "", $value)),
);9.2. Casts
class User extends Model
{
/** * The attributes that should be cast. * * @var array */protected$casts = [
'is_admin' => 'boolean',
];
}class User extends Model
{
/** * The attributes that should be cast. * * @var array */protected$casts = [
'images' => 'collection',
];
}php artisan make:cast PhoneCastnamespaceApp\Casts;
useIlluminate\Contracts\Database\Eloquent\CastsAttributes;
class PhoneCast implements CastsAttributes
{
/** * Cast the given value. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value * @param array $attributes * @return array */publicfunctionget($model, $key, $value, $attributes)
{
return ‘+’ . $value;
}
/** * Prepare the given value for storage. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param array $value * @param array $attributes * @return string */publicfunctionset($model, $key, $value, $attributes)
{
returntrim(preg_replace('/^1|\D/', "", $value));
}
}useApp\Casts\PhoneCast;
class User extends Model
{
/** * The attributes that should be cast. * * @var array */protected$casts = [
'phone' => PhoneCast::class,
];
}Глава 10. Scopes
$posts = Post::query()->where(‘active’, true)->where(‘is_moderated’, true)->where(‘banned’, false)->get()$posts = Post::query()->active()->get()publicfunctionactiveScope(Builder$query)
{
$query->where(‘active’, true)->where(‘is_moderated’, true)->where(‘banned’, false);
}11.1 View
Route::get('/’', function(){ returnview('home’');
});Route::get('/’', function(){ returnview('pages.home’');
});returnview('home’', ['posts' => Post::query()->active()->get()]);<html>
<head>
<title>Cutcode here!</title>
</head>
<body>
<ul>
@foreach($postsas$post)
<li>{{ $post->name }}</li>
@endforeach
</ul>
</body>
</html>@if(true)
@endif @auth @endauth Глава 12. Контроллер
php artisan make:controller HomeController<?phpnamespaceApp\Http\Controllers;
useIlluminate\Http\Request;
class HomeController extends Controller
{
//
}<?phpnamespaceApp\Http\Controllers;
useIlluminate\Http\Request;
class HomeController extends Controller
{
publicfunctionindex()
{
returnview(‘home’, [‘posts’ => Post::query()->active()->get()])
}
}Route::get('/’', [HomeController:class, ‘index’]);Глава 13. Service Container
publicfunctionindexPage(Request$request)
{
}publicfunctionindexPage(User$user)
{
}class Car {
publicfunction__construct(
protectedstring$color
) {}
}publicfunctionindexPage(Car$car)
{
}publicfunctionboot(): void
{
$this->app->instance(Car::class, newCar(‘white’));
}$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);publicfunctionindexPage(Illuminate\Contracts\Http\Kernel$kernel)
{
}publicfunctionboot(): void
{
$this->app->bind(MessengersInterface::class, Telegram::class);
}publicfunctionindexPage(MessengersInterface$messenger)
{
}$this->app->bind(MessengersInterface::class, Slack::class);publicfunctionindexPage()
{
$messenger = app(MessengersInterface::class);
}Глава 13. Два брата Request и Response
<?phpnamespaceApp\Http\Controllers;
useIlluminate\Http\Request;
class HomeController extends Controller
{
publicfunctionindex(Request$request)
{
dump($request->all());
// все параметры реквеста// получим метод запроса GET или POST PUT DELETE и остальные dump($request->method());
// Читаем куку dump($request->cookie(‘name’));
// Берем файл dump($request->file(‘file’));
// Заголовок dump($request->header(‘name’));
returnview(‘home’, [‘posts’ => Post::query()->active()->get()])
}
}returnredirect(‘/’);returnresponse()->json([‘data’ => ‘’]);Глава 14. Валидация
<?phpnamespaceApp\Http\Controllers;
useIlluminate\Http\Request;
class HomeController extends Controller
{
publicfunctionindex(Request$request)
{
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
}
}<input type=”text” name=”title” />
@error(‘title’)
{{ $message }}
@enderrorphp artisan make:request ContactForm<?phpnamespaceApp\Http\Requests;
useIlluminate\Foundation\Http\FormRequest;
class ContactForm extends FormRequest
{
/** * Determine if the user is authorized to make this request. * * @return bool */publicfunctionauthorize()
{
returntrue;
}
/** * Get the validation rules that apply to the request. * * @return array<string, mixed> */publicfunctionrules()
{
return [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
];
}
}<?phpnamespaceApp\Http\Controllers;
useApp\Http\Request\ContactForm;
class HomeController extends Controller
{
publicfunctionindex(ContactForm$request)
{}
}Глава 15. Безопасность
$user[‘about’] = $_POST['about'];
$query = UPDATE users SET about = ‘$user[‘about’]’;“test” AND is_admin = “1’” $query = UPDATE users SET about = ‘$user[‘about’]’;
// UPDATE users SET about = ‘test’ AND is_admin = 1<script>alert('hello, I just hacked this page');</script>{{ $user->about }}{!! $user->about !!} <form action="https://your-application.com/user/email" method="POST">
<input type="email" value="malicious-email@example.com">
</form><form method="POST" action="/profile">
<!-- Выведет hidden input с токеном как и пример ниже ... -->
@csrf
<!-- Тоже самое с помощью токена ... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>session()->put(‘name’, ‘value’); // записали значение в сессию с ключом namesession()->get(‘name’); // получили значение valueif(session()->has(‘name’)) {} // проверили есть ли в сессиях такие данные if(auth()->attempt([‘email’ => request(‘email’), ‘password’ => request(‘password’)])) {
}User::query()->create([
‘email’ => request(‘email’),
‘password’ => Hash::make(‘password’)
])auth()->logout()auth()->login($user)Auth::loginUsingId(1);Route::get(‘/profile’, ProfileController::class)->middleware(‘auth’);Route::get(‘/profile’, ProfileController::class)->middleware(‘guest’);@auth Я {{ auth()->user()->name }} и мой id - {{ auth()->id() }}
@endauth
@guest А здесь будет кнопка “Войти”
@endguestphp artisan make:controller HomeControllerphp artisan make:cast PhoneCast
php artisan make:request ContactFormRequestphp artisan servephp artisan migratephp artisan make:command CreateTestUse<?phpnamespaceApp\Console\Commands;
useIlluminate\Console\Command;
class CreateTestUser extends Command
{
/** * The name and signature of the console command. * * @var string */protected$signature = 'command:name';
/** * The console command description. * * @var string */protected$description = 'Command description';
/** * Execute the console command. * * @return int */publicfunctionhandle()
{
return Command::SUCCESS;
}
}php artisan command:name <?phpnamespaceApp\Console\Commands;
useIlluminate\Console\Command;
class CreateTestUser extends Command
{
/** * The name and signature of the console command. * * @var string */protected$signature = 'create:user';
/** * The console command description. * * @var string */protected$description = 'Create test user';
/** * Execute the console command. * * @return int */publicfunctionhandle()
{
User::create([
‘email’ => ‘test@example.com’
]);
return Command::SUCCESS;
}
}php artisan create:userГлава 19. Сид и нэнси? Почти! Сиды и Фабрики
namespaceDatabase\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;useIlluminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/** * Seed the application's database. * * @return void */publicfunctionrun()
{
// \App\Models\User::factory(10)->create();
}
}class DatabaseSeeder extends Seeder
{
/** * Seed the application's database. * * @return void */publicfunctionrun()
{
OrderStatus::query()->create([‘name’ => ‘new’]);
}
}php artisan migrate –seedphp artisan db:seedphp artisan make:seeder OrderStatusSeeder<?phpnamespaceDatabase\Seeders;
useIlluminate\Database\Console\Seeds\WithoutModelEvents;
useIlluminate\Database\Seeder;
class OrderStatusSeeder extends Seeder
{
/** * Run the database seeds. * * @return void */publicfunctionrun()
{
DB::table(‘order_statuses’)->insert([‘id’ => 1, ‘name’ => ‘Новый’]);
DB::table(‘order_statuses’)->insert([‘id’ => 2, ‘name’ => ‘В обработке’]);
DB::table(‘order_statuses’)->insert([‘id’ => 3, ‘name’ => ‘Подтвержден’]);
DB::table(‘order_statuses’)->insert([‘id’ => 4, ‘name’ => ‘Оплачен’]);
}
}publicfunctionrun()
{
$this->call([
OrderStatusSeeder::class,
]);
}php artisan db:seed --class=OrderStatusSeederphp artisan migrate —-seed --seeder=OrderStatusSeeder<?phpnamespaceDatabase\Factories;
useIlluminate\Database\Eloquent\Factories\Factory;
useIlluminate\Support\Str;
/*** @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>*/class UserFactory extends Factory
{
/** * Define the model's default state. * * @return array<string, mixed> */publicfunctiondefinition()
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password'remember_token' => Str::random(10),
];
}
/** * Indicate that the model's email address should be unverified. * * @return static */publicfunctionunverified()
{
return$this->state(fn (array$attributes) => [
'email_verified_at' => null,
]);
}
}<?phpnamespaceDatabase\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;useIlluminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/** * Seed the application's database. * * @return void */publicfunctionrun()
{
\App\Models\User::factory(100)->create();
}
}php artisan db:seedГлава 20. Тесты
php artisan make:test ArticlesTest<?phpnamespaceTests\Feature;
useIlluminate\Foundation\Testing\RefreshDatabase; useIlluminate\Foundation\Testing\WithFaker;
useTests\TestCase;
class ArticlesTest extends TestCase {
/** * A basic feature test example. * * @return void */publicfunctiontestExample() {
$response = $this->get('/');
$response->assertStatus(200);
} }
php artisan test --filter ArticlestTestOK (1 test, 1 assertion)publicfunction testArticlesPage(){ $this->get('/articles) ->assertSee('All articles');
}