composer create-project laravel/laravel example-app
cd example-app
php artisan serve
php artisan make:controller MyFirstController
php 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->handle
public function handle($request)
{
try {
$request->enableHttpMethodParameterOverride();
$response = $this->sendRequestThroughRouter($request);
} catch (Throwable $e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
}
$this->app['events']->dispatch(
new RequestHandled($request, $response)
);
return $response;
}
$response = $this->sendRequestThroughRouter($request);
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap();
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
###Глава 2. Middleware
public function handle($request, Closure $next)
{
//
return $next($request);
}
return $next($request);
public function handle($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
public function dispatchToRoute(Request $request)
{
return $this->runRoute($request, $this->findRoute($request));
}
public function boot()
{
$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 () {
return view('welcome');
});
###Глава 4. Структура
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
###Глава 5. Конвенция наименований
Глава 6. Миграции
php artisan make:model User -m
php artisan make:migration create_users_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
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
*/
public function down()
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('news', function (Blueprint $table) {
$table->boolean('active')->default(true);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('news', function (Blueprint $table) {
$table->dropColumn('active')
});
}
};
php artisan migrate
php artisan migrate:rollback
php artisan migrate:rollback –step=2
Глава 7. Модели
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Service extends Model
{
}
<?php
namespace App\Models;
use Illuminate\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 = 1 AND 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
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
public function user()
{
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(new User([name => ‘CutCode’]))
$phone->user()->create([‘name’ => ‘CutCode’])
$phone->user()->saveMany([
new User([‘name’ => ‘CutCode’]),
new User([‘name’ => ‘Ivan’])
])
$phone->user()->createMany([
[name => ‘CutCode’],
[name => ‘Ivan’]
])
$phone->user()->update([‘name’ => ‘Oleg’])
$phone->user()->save($user)
$phone->user()->delete()
8.2. HasMany - отношение “Один ко многим”
public function comments()
{
return $this->hasMany(Comment::class);
}
public function post()
{
return $this->belongsTo(Post::class);
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function phone()
{
return $this->hasOne(Phone::class);
}
}
$user->phone->value
public function comments()
{
return $this->hasMany(Comment::class);
}
public function comment()
{
return $this->hasOne(Comment::class);
}
SELECT * FROM comments WHERE post_id = 1;
SELECT * FROM comments WHERE post_id = 1 LIMIT 1;
8.4. Расширенное использование HasOne
public function lastComment(): HasOne
{
return $this->hasOne(Comment::class)->latestOfMany();
}
public function firstComment(): HasOne
{
return $this->hasOne(Comment::class)->oldestOfMany();
}
public function firstComment(): HasOne
{
return $this->hasOne(Comment::class)->oldestOfMany(‘identity’);
}
public function currentPricing()
{
return $this->hasOne(Price::class)->ofMany([
'published_at' => 'max',
'id' => 'max',
], function ($query) {
$query->where('published_at', '<', now());
});
}
public function firstComment(): 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 - integer
Schema::create('role_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete()
->cascadeOnUpdate();
$table->foreignId('role_id')
->constrained()
->cascadeOnDelete()
->cascadeOnUpdate();
$table->timestamps();
});
public function roles()
{
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();
});
public function properties()
{
return $this->belongsToMany(Property::class)
->withPivot(‘value’);
}
foreach ($products->properties as $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 - integer
class Mechanic extends Model
{
/**
* Get the car's owner.
*/
public function carOwner()
{
return $this->hasOneThrough(Owner::class, Car::class);
}
}
public function carOwner()
{
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.
*/
public function carOwners()
{
return $this->hasManyThrough(Owner::class, Car::class);
}
}
class Mechanic extends Model
{
public function carOwners()
{
return $this->through(‘cars’)->has(‘owners’);
}
}
class Mechanic extends Model
{
public function cars()
{
return $this->hasMany(Car::class);
}
}
class Car extends Model
{
public function owners()
{
return $this->hasMany(Owner::class);
}
}
class Car extends Model
{
public function owner()
{
return $this->hasOne(Owner::class);
}
}
class Mechanic extends Model
{
/**
* Get the car's owner.
*/
public function carOwner()
{
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 - string
class Post extends Model
{
/**
* Get all of the post's comments.
*/
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
class Comment extends Model
{
/**
* Get the parent commentable model (post or video).
*/
public function commentable()
{
return $this->morphTo();
}
}
$post->comments
$blog->comments
$new->comments
posts
id - integer
blogs
id - integer
news
id - integer
images
id - integer
url - string
imageable_id - integer
imageable_type - string
class Post extends Model
{
/**
* Get the post's image.
*/
public function image()
{
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 - string
class Tag extends Model
{
/**
* Get all of the posts that are assigned this tag.
*/
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function blogs()
{
return $this->morphedByMany(Blog::class, 'taggable');
}
}
class Post extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
8.9. Eager load
foreach($post->comments as $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 ($posts as $post) {
echo $post->comments_count;
}
$posts = Post::withMax('comments', 'likes')->get();
foreach ($posts as $post) {
echo $post->comments_max_likes;
}
$posts = Post::withAvg('comments', 'votes')->get();
foreach ($posts as $post) {
echo $post->comments_avg_votes;
}
$posts = Post::withSum('comments', 'votes')->get();
foreach ($posts as $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
*/
protected function phone(): Attribute
{
return Attribute::make(
get: fn ($value) => ‘+’ . $value,
);
}
}
class User extends Model
{
/**
* Get the user's first name.
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function name(): 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
*/
protected function phone(): 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 PhoneCast
namespace App\Casts;
use Illuminate\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
*/
public function get($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
*/
public function set($model, $key, $value, $attributes)
{
return trim(preg_replace('/^1|\D/', "", $value));
}
}
use App\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()
public function activeScope(Builder $query)
{
$query->where(‘active’, true)->where(‘is_moderated’, true)->where(‘banned’, false);
}
11.1 View
Route::get('/’', function(){
return view('home’');
});
Route::get('/’', function(){
return view('pages.home’');
});
return view('home’', ['posts' => Post::query()->active()->get()]);
<html>
<head>
<title>Cutcode here!</title>
</head>
<body>
<ul>
@foreach($posts as $post)
<li>{{ $post->name }}</li>
@endforeach
</ul>
</body>
</html>
@if(true)
@endif
@auth
@endauth
Глава 12. Контроллер
php artisan make:controller HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
//
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index()
{
return view(‘home’, [‘posts’ => Post::query()->active()->get()])
}
}
Route::get('/’', [HomeController:class, ‘index’]);
Глава 13. Service Container
public function indexPage(Request $request)
{
}
public function indexPage(User $user)
{
}
class Car {
public function __construct(
protected string $color
) {}
}
public function indexPage(Car $car)
{
}
public function boot(): void
{
$this->app->instance(Car::class, new Car(‘white’));
}
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
public function indexPage(Illuminate\Contracts\Http\Kernel $kernel)
{
}
public function boot(): void
{
$this->app->bind(MessengersInterface::class, Telegram::class);
}
public function indexPage(MessengersInterface $messenger)
{
}
$this->app->bind(MessengersInterface::class, Slack::class);
public function indexPage()
{
$messenger = app(MessengersInterface::class);
}
Глава 13. Два брата Request и Response
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index(Request $request)
{
dump($request->all());
// все параметры реквеста
// получим метод запроса GET или POST PUT DELETE и остальные
dump($request->method());
// Читаем куку
dump($request->cookie(‘name’));
// Берем файл
dump($request->file(‘file’));
// Заголовок
dump($request->header(‘name’));
return view(‘home’, [‘posts’ => Post::query()->active()->get()])
}
}
return redirect(‘/’);
return response()->json([‘data’ => ‘’]);
Глава 14. Валидация
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index(Request $request)
{
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
}
}
<input type=”text” name=”title” />
@error(‘title’)
{{ $message }}
@enderror
php artisan make:request ContactForm
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ContactForm extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
];
}
}
<?php
namespace App\Http\Controllers;
use App\Http\Request\ContactForm;
class HomeController extends Controller
{
public function index(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’); // записали значение в сессию с ключом name
session()->get(‘name’); // получили значение value
if(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
А здесь будет кнопка “Войти”
@endguest
php artisan make:controller HomeController
php artisan make:cast PhoneCast
php artisan make:request ContactFormRequest
php artisan serve
php artisan migrate
php artisan make:command CreateTestUse
<?php
namespace App\Console\Commands;
use Illuminate\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
*/
public function handle()
{
return Command::SUCCESS;
}
}
php artisan command:name
<?php
namespace App\Console\Commands;
use Illuminate\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
*/
public function handle()
{
User::create([
‘email’ => ‘test@example.com’
]);
return Command::SUCCESS;
}
}
php artisan create:user
Глава 19. Сид и нэнси? Почти! Сиды и Фабрики
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// \App\Models\User::factory(10)->create();
}
}
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
OrderStatus::query()->create([‘name’ => ‘new’]);
}
}
php artisan migrate –seed
php artisan db:seed
php artisan make:seeder OrderStatusSeeder
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class OrderStatusSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
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’ => ‘Оплачен’]);
}
}
public function run()
{
$this->call([
OrderStatusSeeder::class,
]);
}
php artisan db:seed --class=OrderStatusSeeder
php artisan migrate —-seed --seeder=OrderStatusSeeder
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\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>
*/
public function definition()
{
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
*/
public function unverified()
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
\App\Models\User::factory(100)->create();
}
}
php artisan db:seed
Глава 20. Тесты
php artisan make:test ArticlesTest
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class ArticlesTest extends TestCase {
/**
* A basic feature test example.
*
* @return void
*/
public function testExample() {
$response = $this->get('/');
$response->assertStatus(200);
} }
php artisan test --filter ArticlestTest
OK (1 test, 1 assertion)
public function testArticlesPage(){
$this->get('/articles)
->assertSee('All articles');
}