라라벨 팁 한국어

라라벨 개발자들을 위한 멋진 Laravel 팁과 트릭 모음입니다. PR 및 아이디어를 환영합니다!
이 문서는 PovilasKoropMarceauKa 의 아이디어를 번역한 문서입니다.

2021 년 1 월 29 일 업데이트 : 현재 125 개의 팁 이 14 개 섹션으로 나뉩니다.

DB 모델 및 Eloquent

⬆️ 맨 위로 이동 ➡️ 다음 (모델 관계)

Eloquent 날짜 관련 검색 메서드

whereDay() , whereMonth() , whereYear() , whereDate()whereTime() 함수로 날짜를 검색하십시오.

$products = Product::whereDate('created_at', '2018-01-31')->get();
$products = Product::whereMonth('created_at', '12')->get();
$products = Product::whereDay('created_at', '31')->get();
$products = Product::whereYear('created_at', date('Y'))->get();
$products = Product::whereTime('created_at', '=', '14:13:58')->get();

값의 증가 및 감소

일부 테이블에서 일부 DB 컬럼의 값을 증가 시키려면 increment() 함수를 사용하십시오. 아, 그리고 당신은 1만큼 증가시킬 수있을뿐만 아니라 50과 같은 어떤 숫자도 증가시킬 수 있습니다.

Post::find($post_id)->increment('view_count');
User::find($user_id)->increment('points', 50);

타임 스탬프 컬럼이 없을 때

DB 테이블에 타임 스탬프 필드 created_atupdated_at가 포함되어 있지 않은 경우, $timestamps = false를 사용하여 Eloquent 모델이 이 속성을 사용하지 않도록 지정할 수 있습니다.

class Company extends Model
{
    public $timestamps = false;
}

옵저버로 로그인 한 사용자 지정

현재 로그인 한 사용자를 user_id 필드에 자동으로 지정되게하려면 make:observer 를 사용하고 creating() 메서드를 추가합니다.

class PostObserver
{
    public function creating(Post $post)
    {
        $post->user_id = auth()->id();
    }
}

소프트 삭제 : 다중 복원

소프트 삭제를 사용하면 한 문장으로 여러 행을 복원 할 수 있습니다.

Post::withTrashed()->where('author_id', 1)->restore();

Model::all의 컬럼 지정

Eloquent의 Model::all() 호출 할 때 반환 할 열을 지정할 수 있습니다.

$users = User::all(['id', 'name', 'email']);

실패하거나 실패하지 않기

findOrFail() 외에도 쿼리에 대한 레코드가없는 경우 404 페이지를 반환하는 Eloquent 메서드 firstOrFail()도 있습니다.

$user = User::where('email', 'povilas@laraveldaily.com')->firstOrFail();

열 이름 변경

Eloquent Query Builder에서 "as"를 지정하여 일반 SQL 쿼리처럼 다른 이름을 가진 열을 반환 할 수 있습니다.

$users = DB::table('users')->select('name', 'email as user_email')->get();

쿼리 결과에 대한 개별 수정

Eloquent 쿼리 후에 Collections에서 map() 함수를 사용하여 행을 수정할 수 있습니다.

$users = User::where('role_id', 1)->get()->map(function (User $user) {
    $user->some_column = some_function($user);
    return $user;
});

기본 타임 스탬프 필드 변경

Laravel이 아닌 데이터베이스로 작업하고 있고 타임스탬프 열의 이름이 다르다면 어떻게 해야할까요? 아마도 create_time 이나 update_time 같은 열이 있을 겁니다. 다행히도 모델에서 변경 할 수 있습니다.

class Role extends Model
{
    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';
}

created_at을 손쉽게 정렬하기

이것을

User::orderBy('created_at', 'desc')->get();

더 쉽게 할 수 있습니다.

User::latest()->get();

기본적으로 latest()created_at을 이용하여 정렬합니다.

created_at 오름차순으로 정렬하는, 반대 메소드 oldest()도 있습니다.

User::oldest()->get();

또한 정렬할 열을 바꿀 수도 있습니다. 예를 들어 updated_at 를 사용하려면 아래처럼 사용하면 됩니다.

$lastUpdatedUser = User::latest('updated_at')->first();

레코드 생성시 자동으로 생성되는 열 값

레코드 생성시 DB 컬럼 값을 생성하려면 모델의 boot() 메소드에 추가합니다. 예를 들어 "position"필드가 있고 사용 가능한 다음 위치를 새 레코드에 할당하려면 (예 Country::max('position') + 1) 과 같이하십시오.

class Country extends Model {
    protected static function boot()
    {
        parent::boot();

        Country::creating(function($model) {
            $model->position = Country::max('position') + 1;
        });
    }
}

DB Raw 쿼리 계산을 더 빠르게

whereRaw() 메서드와 같은 SQL 원시 쿼리를 사용하여 일부 DB 특정 계산을 Laravel이 아닌 쿼리에서 직접 수행하면 일반적으로 결과가 더 빠릅니다. 예를 들어, 등록 후 30 일 이상 활성 상태였던 사용자를 얻으려면 다음 코드를 사용하십시오. (역자: 단 이 경우는 ORM의 장점인 추상화의 이점을 얻지 못하고 특정 데이터베이스에 종속되는 사이드이펙트가 생길 수 있습니다. 이 부분을 감안하고 사용하시기 바랍니다. 이것은 사용하지 말라는 의미가 아닌 주의를 필요로 하는 의미로 남기는 글입니다.)

User::where('active', 1)
    ->whereRaw('TIMESTAMPDIFF(DAY, created_at, updated_at) > ?', 30)
    ->get();

한개 이상의 스코프

쿼리에서 하나 이상의 스코프를 사용하여 Eloquent에서 쿼리 스코프를 결합하고 연결할 수 있습니다.

모델:

public function scopeActive($query) {
    return $query->where('active', 1);
}

public function scopeRegisteredWithinDays($query, $days) {
    return $query->where('created_at', '>=', now()->subDays($days));
}

일부 컨트롤러 :

$users = User::registeredWithinDays(30)->active()->get();

카본을 전환해줄 필요가 없습니다

whereDate()를 이용해 오늘 기준의 레코드를 조회할 경우 Carbon의 now()를 사용할 수 있으며, 자동으로 날짜 형식으로 변환됩니다. 이때 ->toDateString()를 해줄 필요가 없습니다.

// 이럴땐
$todayUsers = User::whereDate('created_at', now()->toDateString())->get();
// 전환할 필요가 없습니다. 그냥 now()를 쓰세요
$todayUsers = User::whereDate('created_at', now())->get();

첫 글자로 그룹화

사용자 지정 조건별로 Eloquent 결과를 그룹화 할 수 있습니다. 사용자 이름의 첫 글자로 그룹화하는 방법은 다음과 같습니다.

$users = User::all()->groupBy(function($item) {
    return $item->name[0];
});

열 업데이트 안 함

한 번만 설정하고 다시 업데이트하지 않으려는 DB 열이있는 경우 뮤 테이터를 사용하여 Eloquent Model에 해당 제한을 설정할 수 있습니다.

class User extends Model
{
    public function setEmailAttribute($value)
    {
        if ($this->email) {
            return;
        }

        $this->attributes['email'] = $value;
    }
}

여러개를 찾기

Eloquent 메소드 find() 는 여러 매개 변수를 받아 들일 수 있으며, 하나의 모델이 아닌 발견 된 모든 레코드의 컬렉션을 반환합니다.

// Eloquent Model을 반환합니다
$user = User::find(1);
// Eloquent Collection을 반환합니다
$users = User::find([1,2,3]);

Key로 찾기

정확히 어떤 필드가 기본 키인지에 따라 자동으로 처리하는 whereKey() 메서드를 사용하여 여러 레코드를 찾을 수도 있습니다 ( 기본값은 id 지만 Eloquent 모델에서 재정의 할 수 있습니다).

$users = User::whereKey([1,2,3])->get();

자동 증가 대신 UUID 사용

모델에서 자동 증분 ID를 사용하고 싶지 않습니까?

마이그레이션:

Schema::create('users', function (Blueprint $table) {
    // $table->increments('id');
    $table->uuid('id')->unique();
});

모델:

class User extends Model
{
    public $incrementing = false;
    protected $keyType = 'string';

    protected static function boot()
    {
        parent::boot();

        User::creating(function ($model) {
            $model->setId();
        });
    }

    public function setId()
    {
        $this->attributes['id'] = Str::uuid();
    }
}

Laravel에서 sub select 사용법

Laravel 6에서는 Eloquent 문에서 addSelect()를 사용하여 추가 된 열에 대해 계산을 할 수 있습니다.

return Destination::addSelect(['last_flight' => Flight::select('name')
    ->whereColumn('destination_id', 'destinations.id')
    ->orderBy('arrived_at', 'desc')
    ->limit(1)
])->get();

일부 열 숨기기

Eloquent 쿼리를 수행 할 때 특정 필드가 반환되는 것을 숨기려면 가장 빠른 방법 중 하나는 Collection 결과에 ->makeHidden() 을 추가하는 것입니다.

$users = User::all()->makeHidden(['email_verified_at', 'deleted_at']);

정확한 DB 오류

Eloquent Query 예외를 잡으려면 기본 Exception 클래스 대신 특정 QueryException을 사용하면 오류의 정확한 SQL 코드를 얻을 수 있습니다.

try {
    // Some Eloquent/SQL statement
} catch (\Illuminate\Database\QueryException $e) {
    if ($e->getCode() === '23000') { // integrity constraint violation
        return back()->withError('Invalid data');
    }
}

쿼리 빌더에서의 소프트 삭제

소프트 삭제는 Eloquent를 사용할 때는 삭제된 항목을 제외하지만 Query Builder를 사용하면 작동하지 않는다는 것을 잊지 마십시오.

// Will exclude soft-deleted entries
$users = User::all();

// Will NOT exclude soft-deleted entries
$users = DB::table('users')->get();

올바른 오래된 SQL 쿼리

DB 스키마에서 무언가를 변경하는 것과 같은 결과를 얻지 않고 간단한 SQL 쿼리를 실행해야하는 경우 DB::statement() 됩니다.

DB::statement('DROP TABLE users');
DB::statement('ALTER TABLE projects AUTO_INCREMENT=123');

DB 트랜잭션 사용 <a id="use-db-transactions>

두 개의 DB 작업을 수행하고 두 번째 작업에서 오류가 발생할 수있는 경우 첫 번째 작업을 롤백해야합니다.

이를 위해 DB 트랜잭션을 사용하는 것이 좋습니다. Laravel에서는 정말 쉽습니다.

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});

업데이트 또는 생성

레코드가 있는지 확인한 다음 업데이트하거나 새 레코드를 만들어야하는 경우 한 문장으로 수행 할 수 있습니다. Eloquent 메서드 updateOrCreate()를 사용합니다.

// Instead of this
$flight = Flight::where('departure', 'Oakland')
    ->where('destination', 'San Diego')
    ->first();
if ($flight) {
    $flight->update(['price' => 99, 'discounted' => 1]);
} else {
    $flight = Flight::create([
        'departure' => 'Oakland',
        'destination' => 'San Diego',
        'price' => 99,
        'discounted' => 1
    ]);
}
// Do it in ONE sentence
$flight = Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99, 'discounted' => 1]
);

저장시 캐시 삭제

@pratiksh404 가 제공 한 팁

컬렉션을 제공하는 posts 과 같은 캐시 키가 있고 새 저장소 또는 업데이트에서 해당 캐시 키를 잊고 싶다면 모델에서 정적 saving 기능을 호출 할 수 있습니다.

class Post extends Model
{
    // Forget cache key on storing or updating
    public static function boot()
    {
        parent::boot();
        static::saving(function () {
           Cache::forget('posts');
        });
    }
}

Created_at 및 Updated_at의 형식 변경

@syofyanzuhad 가 제공 한 팁

created_at 형식을 변경하려면 다음과 같이 모델에 메소드를 추가 할 수 있습니다.

public function getCreatedAtFormattedAttribute()
{
   return $this->created_at->format('H:i d, M Y');
}

따라서 필요할 때 $entry->created_at_formatted 사용할 수 있습니다. 다음과 같이 created_at 속성이 반환됩니다 : 04:19 23, Aug 2020 .

또한 updated_at 속성의 형식을 변경하려면 다음 메소드를 추가 할 수 있습니다.

public function getUpdatedAtFormattedAttribute()
{
   return $this->updated_at->format('H:i d, M Y');
}

따라서 필요할 때 $entry->updated_at_formatted 사용할 수 있습니다. 다음과 같이 updated_at 속성이 반환됩니다 : 04:19 23, Aug 2020 .

JSON에 배열 유형 저장

@pratiksh404 가 제공 한 팁

배열을 사용하는 입력 필드가 있고이를 JSON으로 저장해야하는 경우 모델에서 $casts 속성을 사용할 수 있습니다. 여기 images 는 JSON 속성입니다.

protected $casts = [
    'images' => 'array',
];

따라서 JSON으로 저장할 수 있지만 DB에서 검색하면 배열로 사용할 수 있습니다.

모델 사본 만들기

두 개의 매우 유사한 모델 (배송 주소 및 청구 주소)이 있고 서로 사본을 만들어야하는 경우 replicate() 메서드를 사용하고 그 후에 일부 속성을 변경할 수 있습니다.

공식 문서의 예 :

$shipping = Address::create([
    'type' => 'shipping',
    'line_1' => '123 Example Street',
    'city' => 'Victorville',
    'state' => 'CA',
    'postcode' => '90001',
]);

$billing = $shipping->replicate()->fill([
    'type' => 'billing'
]);

$billing->save();

모델 관계

⬆️ 맨 위로 이동 ⬅️ 이전 (DB 모델 및 Eloquent) ➡️ 다음 (마이그레이션)

Eloquent 관계에 대한 OrderBy

Eloquent 관계에서 직접 orderBy()를 지정할 수 있습니다.

public function products()
{
    return $this->hasMany(Product::class);
}

public function productsByName()
{
    return $this->hasMany(Product::class)->orderBy('name');
}

조건부 관계

추가 "where"조건과 함께 동일한 관계를 자주 사용하는 경우 별도의 관계 방법을 만들 수 있습니다.

모델:

public function comments()
{
    return $this->hasMany(Comment::class);
}

public function approved_comments()
{
    return $this->hasMany(Comment::class)->where('approved', 1);
}

Raw DB 쿼리: havingRaw()

havingRaw() 이후의 groupBy() 함수를 포함하여 다양한 위치에서 RAW DB 쿼리를 사용할 수 있습니다.

Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();

Eloquent has()를 더 깊게

Eloquent has() 함수를 사용하여 두 단계의 관계를 쿼리 할 수 있습니다!

// Author -> hasMany(Book::class);
// Book -> hasMany(Rating::class);
$authors = Author::has('books.ratings')->get();

Has Many. 정확히 얼마나 많은 것을 원하나요?

Eloquent hasMany() 관계에서 지정한 양의 하위 레코드가 있는 레코드를 필터링 할 수 있습니다.

// Author -> hasMany(Book::class)
$authors = Author::has('books', '>', 5)->get();

기본 모델

$post->user가 존재하지 않는 경우 {{ $post->user->name }} 과 같이 호출 할 때 치명적인 오류를 방지하기 위해 belongsTo 관계에 기본 모델을 할당 할 수 있습니다.

public function user()
{
    return $this->belongsTo('App\User')->withDefault();
}

hasMany를 이용한 다중 생성

hasMany() 관계가있는 경우 saveMany() 를 사용하여 "부모"개체의 여러 "자식"항목을 모두 한 문장으로 저장할 수 있습니다.

$post = Post::find(1);
$post->comments()->saveMany([
    new Comment(['message' => 'First comment']),
    new Comment(['message' => 'Second comment']),
]);

빠른 로딩에서 필요한 컬럼만 사용하기

Laravel Eager Loading을 실행할 때 관계에서 필요한 컬럼만 가져올 수 있습니다.

$users = App\Book::with('author:id,name')->get();

한단계를 거치는 관계에서도 사용 할 수 있습니다.

$users = App\Book::with('author.country:id,name')->get();

쉽게 상위 모델의 updated_at 갱신하기

레코드를 업데이트하고 상위 관계의 updated_at 열을 갱신하려면 (예 : 새 댓글을 추가하고 게시글 posts.updated_at를 갱신하려는 경우) 자식 모델에 $touches = ['post'];속성을 추가.

class Comment extends Model
{
    protected $touches = ['post'];
}

관계가 존재하는지 항상 확인하세요

지금까지는 $model->relationship->field처럼 관계 객체가 여전히 존재하는지 확인하지 않고 사용했습니다.

현재 동작하는 코드 외부, 즉 다른 사람의 대기열 작업 등 어떤 이유로든 관계는 삭제 될 수 있습니다. if-else , 또는 {{ $model->relationship->field ?? '' }} 또는 (블레이드){{ optional($model->relationship)->field }}를 사용하세요.

withCount()를 사용하여 하위 관계 레코드의 갯수 확인

hasMany() 관계에서 "자식"항목을 갯수를 확인하려면 쿼리를 따로 작성하지 마세요. 예를 들어, User 모델에 대한 게시물과 댓글이 있을 경우 withCount() 사용하세요.

public function index()
{
    $users = User::withCount(['posts', 'comments'])->get();
    return view('users', compact('users'));
}

그런 다음 블레이드 파일에서 {relationship}_count 속성을 사용하여 해당 갯수를 가져올 수 있습니다.

@foreach ($users as $user)
<tr>
    <td>{{ $user->name }}</td>
    <td class="text-center">{{ $user->posts_count }}</td>
    <td class="text-center">{{ $user->comments_count }}</td>
</tr>
@endforeach

해당 필드로 정렬할 수도 있습니다.

User::withCount('comments')->orderBy('comments_count', 'desc')->get();

관계에서 필터 쿼리 추가하기

관계 데이터를 불러올때 클로저 함수에서 몇 가지 제한 또는 순서를 지정할 수 있습니다. 예를 들어, 가장 큰 도시가 3 개만 있는 국가를 얻으려면 다음과 같이 코드를 작성하면 됩니다.

$countries = Country::with(['cities' => function($query) {
    $query->orderBy('population', 'desc');
    $query->take(3);
}])->get();

관계를 항상 로드하지만 동적으로도 로드하기

모델과 함께 항상 로드 할 관계를 지정할 수 있을 뿐만 아니라 생성자 메서드에서 동적으로 처리할 수도 있습니다.

class ProductTag extends Model
{
    protected $with = ['product'];

    public function __construct() {
        parent::__construct();
        $this->with = ['product'];

        if (auth()->check()) {
            $this->with[] = 'user';
        }
    }
}

belongsTo 대신 hasMany를 사용하세요.

belongsTo 관계에서 하위 레코드를 만들 때 부모의 ID를 전달하는 방식 대신, hasMany 관계를 사용하여 더 짧은 문장을 만들 수 있습니다.

// 만약 Post -> belongsTo(User)이고, User -> hasMany(Post) 라면...
// user_id를 넘겨주는 대신...
Post::create([
    'user_id' => auth()->id(),
    'title' => request()->input('title'),
    'post_text' => request()->input('post_text'),
]);

// 이렇게 사용하세요
auth()->user()->posts()->create([
    'title' => request()->input('title'),
    'post_text' => request()->input('post_text'),
]);

피벗 테이블 이름 바꾸기

"pivot"단어의 이름을 바꾸고 관계를 다른 이름으로 부르려면 관계에서 ->as('name') 를 사용하면됩니다.

모델:

public function podcasts() {
    return $this->belongsToMany('App\Podcast')
        ->as('subscription')
        ->withTimestamps();
}

컨트롤러:

$podcasts = $user->podcasts();
foreach ($podcasts as $podcast) {
    // $podcast->pivot->created_at 대신에...
    echo $podcast->subscription->created_at;
}

한 줄로 상위 모델 업데이트

belongsTo() 관계일 경우 한 문장으로 Eloquent 관계 데이터를 업데이트 할 수 있습니다.

// 만약 Project -> belongsTo(User::class)이라면
$project->user->update(['email' => 'some@gmail.com']);

Laravel 7이상에서 외래 키

Laravel 7부터 마이그레이션시 관계 필드에 대해 두 줄을 작성할 필요가 없습니다. 하나는 필드 용이고 다른 하나는 외래 키용입니다. foreignId() 메소드를 사용하십시오.

// Laravel 7 이전
Schema::table('posts', function (Blueprint $table)) {
    $table->unsignedBigInteger('user_id');
    $table->foreign('user_id')->references('id')->on('users');
}

// Laravel 7 부터
Schema::table('posts', function (Blueprint $table)) {
    $table->foreignId('user_id')->constrained();
}

// 또는, 필드가 참조 테이블과 다른 경우
Schema::table('posts', function (Blueprint $table)) {
    $table->foreignId('created_by_id')->constrained('users', 'column');
}

두 "whereHas"결합

Eloquent에서는 whereHas()orDoesntHave()을 한 문장으로 결합 할 수 있습니다.

User::whereHas('roles', function($query) {
    $query->where('id', 1);
})
->orDoesntHave('roles')
->get();

관계 메서드가 있는지 확인하기

Eloquent 관계 이름이 동적이고 해당 이름과의 관계가 객체에 존재하는지 확인해야 하는 경우 PHP 함수 method_exists($object, $methodName)를 사용하세요.

$user = User::first();
if (method_exists($user, 'roles')) {
    // $user->roles()-> 와 함께 관계 메서드 사용하기...
}

추가 관계가 있는 피벗 테이블

다대다 관계에서 피벗 테이블에는 추가 필드 및 다른 모델에 대한 추가 관계가 포함될 수 있습니다.

다음과 같이 별도의 피벗 모델을 생성합니다.

php artisan make:model RoleUser --pivot

그다음 ->using() 메서드를 사용하여 belongsToMany()에 지정합니다. 그러면 다음 예제와 같이 쩌는 것을 할 수 있습니다.

// app/Models/User.php 에서
public function roles()
{
    return $this->belongsToMany(Role::class)
        ->using(RoleUser::class)
        ->withPivot(['team_id']);
}

// app/Models/RoleUser.php 모델은 Model이 아닌 Illuminate\Database\Eloquent\Relations\Pivot을 확장하여 사용합니다;

class RoleUser extends Pivot
{
    public function team()
    {
        return $this->belongsTo(Team::class);
    }
}

// 그러면 Controller에서 아래와 같이 실행할 수 있습니다.
$firstTeam = auth()->user()->roles()->first()->pivot->team->name;

즉석으로 관계 갯수 구해오기

관련 레코드의 갯수를 가져오기 위해 Eloquent의 withCount() 메서드 외에도 loadCount()를 사용하여 즉석으로 갯수를 가져올 수 도 있습니다.

// 만약 Book이 여러개의 Reviews를 가지고 있다면...
$book = App\Book::first();

$book->loadCount('reviews');
// $book->reviews_count; 를 사용할 수 있습니다

// 또 추가 조건과 함께도 가능합니다
$book->loadCount(['reviews' => function ($query) {
    $query->where('rating', 5);
}]);

관계 순서 무작위 화

inRandomOrder()를 사용하여 Eloquent 쿼리 결과를 무작위화 할 수 있지만 이를 사용하여 쿼리로 로드하는 relationship 항목을 무작위화 할 수도 있습니다.

// 퀴즈가 있고 질문을 무작위로 선택하려는 경우...

// 1. 무작위 순서로 질문을 받고 싶다면
$questions = Question::inRandomOrder()->get();

// 2. 무작위 순서로 질문 옵션을 가져오려면 다음과 같이 사용하세요.
$questions = Question::with(['answers' => function($q) {
    $q->inRandomOrder();
}])->inRandomOrder()->get();

마이그레이션

⬆️ 맨 위로 이동 ⬅️ 이전 (모델 관계) ➡️ 다음 (보기)

부호없는 정수

외래 키 마이그레이션의 경우 integer() 대신 unsignedInteger() 유형 또는 integer()->unsigned()를 사용하세요 . 그렇지 않으면 SQL 오류가 발생할 수 있습니다.

Schema::create('employees', function (Blueprint $table) {
    $table->unsignedInteger('company_id');
    $table->foreign('company_id')->references('id')->on('companies');
    // ...
});

다른 열이 bigInteger() 유형 인 경우 unsignedBigInteger() 사용할 수도 있습니다.

Schema::create('employees', function (Blueprint $table) {
    $table->unsignedBigInteger('company_id');
});

마이그레이션 순서

당신은 DB 마이그레이션의 순서를 변경하려면, 단지 다음과 같이 파일에서 타임 스탬프만 바꾸면 됩니다. 2018_08_04_070443_create_posts_table.php 에서 2018_07_04_070443_create_posts_table.php 로 변경. (2018_08_04 에서 2018_07_04 로 변경).

마이그레이션은 알파벳 순서로 실행됩니다.

시간대가 있는 마이그레이션 필드

마이그레이션에서 timezone에 대한 timetamps timestamps() 뿐만 아니라 timestampsTz() 도 있다는 것을 알고 계셨습니까?

Schema::create('employees', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email');
    $table->timestampsTz();
});

또한 dateTimeTz() , timeTz() , timestampTz() , softDeletesTz() 도 있습니다.

데이터베이스 마이그레이션 열 유형

마이그레이션을 위한 재밌는 열 유형이 있습니다. 몇 가지 예를 보여드리겠습니다.

$table->geometry('positions');
$table->ipAddress('visitor');
$table->macAddress('device');
$table->point('position');
$table->uuid('id');

공식 문서 에서 모든 열 유형을 참조하십시오.

기본 타임 스탬프

마이그레이션을 생성하는 동안 useCurrent() 옵션과 함께 timestamp() 열 유형을 사용할 수 있으며 CURRENT_TIMESTAMP 를 기본값으로 설정합니다.

$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();

마이그레이션 상태

어떤 마이그레이션이 아직 실행되지 않았는지 확인하고 싶을때, 굳이 데이터베이스에서 "migrations"테이블을 볼 필요가 없습니다. php artisan migrate:status 명령을 실행해보세요.

결과 예 :

+------+------------------------------------------------+-------+
| Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | 2014_10_12_000000_create_users_table           | 1     |
| Yes  | 2014_10_12_100000_create_password_resets_table | 1     |
| No   | 2019_08_19_000000_create_failed_jobs_table     |       |
+------+------------------------------------------------+-------+

공백과 함께 마이그레이션 만들기

make:migration 명령어를 입력 할 때 create_transactions_table과 같이 부분 사이에 반드시 밑줄 _ 기호를 사용할 필요는 없습니다. 이름을 따옴표로 묶은 다음 밑줄 대신 공백을 사용할 수 있습니다.

// This works
php artisan make:migration create_transactions_table

// But this works too
php artisan make:migration "create transactions table"

출처 : Twitter의 Steve O

다른 열 뒤에 열 만들기

기존 테이블에 새 열을 추가할 때 반드시 마지막 열로 만들 필요는 없습니다. 생성해야 하는 열을 특정 열의 뒤로 지정할 수 있습니다.

Schema::table('users', function (Blueprint $table) {
    $table->string('phone')->after('email');
});

⬆️ 맨 위로 이동 ⬅️ 이전 (마이그레이션) ➡️ 다음 (라우팅)

foreach의 $loop 변수

foreach 루프 내에서 $loop 변수를 사용하여 현재 항목이 처음 / 마지막인지 확인합니다.

@foreach ($users as $user)
     @if ($loop->first)
        This is the first iteration.
     @endif

     @if ($loop->last)
        This is the last iteration.
     @endif

     <p>This is user {{ $user->id }}</p>
@endforeach

$loop->iteration 또는 $loop->count 와 같은 다른 속성도 있습니다. 공식 문서 에서 자세히 알아보십시오.

뷰 파일이 있습니까?

실제로 뷰를 로드하기 전에 해당 뷰 파일이 있는지 확인할 수 있습니다.

if (view()->exists('custom.page')) {
 // Load the view
}

로드 할 뷰 배열을 사용 할 수도 있으며, 이때는 처음 존재하는 뷰만 실제로 로드됩니다.

return view()->first(['custom.dashboard', 'dashboard'], $data);

오류 코드 블레이드 페이지

500과 같은 일부 HTTP 코드에 대한 특정 오류 페이지를 생성하려면 이 코드를 파일 이름으로 resources/views/errors/500.blade.php 또는 403.blade.php 등으로 블레이드 파일을 만드세요. 해당 오류 코드에 맞게 자동으로 로드됩니다.

컨트롤러 없이 뷰 사용하기

라우트가 특정 뷰만 보여준다면 Controller를 생성하지 말고 Route::view() 함수를 사용하십시오.

// 이것처럼 되어있거나
Route::get('about', 'TextsController@about');
// 이것처럼 되어있다면
class TextsController extends Controller
{
    public function about()
    {
        return view('texts.about');
    }
}
// 이렇게 사용하세요
Route::view('about', 'texts.about');

블레이드 @auth

로그인 한 사용자를 확인하기위해 if 문 대신 @auth 지시문을 사용하세요.

일반적인 방법 :

@if(auth()->user())
    // The user is authenticated.
@endif

짧게 :

@auth
    // The user is authenticated.
@endauth

반대는 @guest 지시문입니다.

@guest
    // The user is not authenticated.
@endguest

블레이드의 2 단계 $loop 변수

Blade의 foreach에서는 2 단계 루프에서도 $loop 변수를 사용하여 상위 변수에 접근 할 수 있습니다.

@foreach ($users as $user)
    @foreach ($user->posts as $post)
        @if ($loop->parent->first)
            This is first iteration of the parent loop.
        @endif
    @endforeach
@endforeach

나만의 블레이드 지시문 만들기

진짜 쉽습니다. app/Providers/AppServiceProvider.php 에 자신만의 메서드를 추가하기만 하면됩니다. 예를 들어, <br> 태그를 엔터로 바꾸려면 다음과 같이하십시오.

// 블레이드에서
<textarea>@br2nl($post->post_text)</textarea>

이 지시문을 AppServiceProvider의 boot() 메서드에 추가합니다.

public function boot()
{
    Blade::directive('br2nl', function ($string) {
        return "<?php echo preg_replace('/\<br(\s*)?\/?\>/i', \"\n\", $string); ?>";
    });
}

블레이드 지시문 : IncludeIf, IncludeWhen, IncludeFirst

Blade 부분적으로 사용하는 파일이 실제로 존재하는지 확실하지 않은 경우 다음 조건 명령을 사용할 수 있습니다.

블레이드 파일이 있는 경우에만 헤더를 로드합니다.

@includeIf('partials.header')

role_id가 1 인 사용자에 대해서만 헤더를로드합니다.

@includeWhen(auth()->user()->role_id == 1, 'partials.header')

adminlte.header를 로드하려고 시도합니다. 해당 파일이 없을 경우에만 default.header를 로드합니다.

@includeFirst('adminlte.header', 'default.header')

라우팅

⬆️ 맨 위로 이동 ⬅️ 이전 (뷰) ➡️ 다음 (유효성 검사)

그룹 내의 라우팅 그룹

라우트에서 그룹 내 그룹을 생성하여, 특정 미들웨어를 "상위"그룹의 일부 URL에만 할당 할 수 있습니다.

Route::group(['prefix' => 'account', 'as' => 'account.'], function() {
    Route::get('login', 'AccountController@login');
    Route::get('register', 'AccountController@register');

    Route::group(['middleware' => 'auth'], function() {
        Route::get('edit', 'AccountController@edit');
    });
});

와일드 카드 하위 도메인

동적인 하위 도메인 이름으로 라우트 그룹을 생성하고 해당 값을 모든 경로에 전달할 수 있습니다.

Route::domain('{username}.workspace.com')->group(function () {
    Route::get('user/{id}', function ($username, $id) {
        //
    });
});

라우트 뒤에는 무엇이 있을까요?

Auth::routes() 에 실제로 어떤 경로들이 있는지 알고 싶나요? Laravel 7부터는 별도의 패키지에 있는 /vendor/laravel/ui/src/AuthRouteMethods.php 파일을 확인해보세요.

public function auth()
{
    return function ($options = []) {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');
        // Registration Routes...
        if ($options['register'] ?? true) {
            $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
            $this->post('register', 'Auth\RegisterController@register');
        }
        // Password Reset Routes...
        if ($options['reset'] ?? true) {
            $this->resetPassword();
        }
        // Password Confirmation Routes...
        if ($options['confirm'] ?? class_exists($this->prependGroupNamespace('Auth\ConfirmPasswordController'))) {
            $this->confirmPassword();
        }
        // Email Verification Routes...
        if ($options['verify'] ?? false) {
            $this->emailVerification();
        }
    };
}

Laravel 7 이전이라면 /vendor/laravel/framework/src/illuminate/Routing/Router.php 파일을 확인해보세요.

라우트에서 모델 바인딩 : 키를 지정 할 수 있습니다.

라우트에 모델을 Route::get('api/users/{user}', function (App\User $user) { … } 이런식으로 ID 필드를 기준으로 바인딩 할 수 있을 뿐만 아니라, {user}username 필드로 변경하고 싶다면 다음과 같이 모델에 입력하면 됩니다.

public function getRouteKeyName() {
    return 'username';
}

Routes 파일에서 컨트롤러로 빠르게 이동

이것은 Laravel 8 이전에는 선택 사항이었으며 Laravel 8에서 라우팅의 표준 기본 구문이되었습니다.

다음과 같이 라우팅하는 대신

Route::get('page', 'PageController@action');

컨트롤러를 클래스로 지정할 수 있습니다.

Route::get('page', [\App\Http\Controllers\PageController::class, 'action']);

그런 다음 PhpStorm에서 PageController 를 클릭하고 수동으로 검색하는 대신 Controller로 직접 이동할 수 있습니다.

또 길이를 줄이려면 다음과 같이 Routes 파일의 맨 위에 use 구분을 추가하십시오.

use App\Http\Controllers\PageController;

// 요롷게~
Route::get('page', [PageController::class, 'action']);

대체 라우트 : 일치하는 다른 경로가 없는 경우

찾을 수 없는 경로에 대한 추가 로직을 지정하려면 기본 404 페이지를 표시하는 대신 라우트 파일의 맨 끝에 특수 경로를 만들 수 있습니다.

Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
    Route::get('/home', 'HomeController@index');
    Route::resource('tasks', 'Admin\TasksController');
});

// Some more routes....
Route::fallback(function() {
    return 'Hm, why did you land here somehow?';
});

정규식을 사용한 라우트 매개 변수 유효성 검사

"where"매개 변수를 사용하여 경로에서 직접 매개 변수를 검증 할 수 있습니다. 일반적으로 경로에 fr/blogen/article/333 과 같이 언어 로케일로 접두사를 지정하는 경우가 있습니다. 이때 두 개의 첫 글자가 영어가 아닌 다른 언어가 사용되지 않도록하려면 어떻게해야 할까요?

routes/web.php :

Route::group([
    'prefix' => '{locale}',
    'where' => ['locale' => '[a-zA-Z]{2}']
], function () {
    Route::get('/', 'HomeController@index');
    Route::get('article/{id}', 'ArticleController@show');
});

속도 제한 : 글로벌 및 게스트 / 사용자 용

throttle:60,1을 사용하여 일부 URL은 분당 최대 60 회 호출되도록 제한 할 수 있습니다.

Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

또한 게스트 및 로그인 한 사용자에 대해 별도로 지정 할 수 있습니다.

// 게스트에 대해 최대 10 개의 요청, 인증 된 사용자에 대해 60 개
Route::middleware('throttle:10|60,1')->group(function () {
    //
});

또한 DB 필드 users.rate_limit를 사용해 특정 사용자에 대한 제한 지정 할 수 있습니다.

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

라우트에 매개 변수로 쿼리스트링을 추가하기

라우트에 추가 매개 변수를 전달하면 배열의 키/값이 생성 될 URL의 쿼리 문자열에 자동으로 추가됩니다.

Route::get('user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1, 'photos' => 'yes']); // Result: /user/1/profile?photos=yes

파일별로 라우트 분리

특정 "섹션"에 관한 경로가 셋트로 있는 경우, 별도의 routes/XXXXX.php 같은 파일로 분리해서 routes/web.php에 포함시킬 수 있습니다

Taylor Otwell이 직접 만든 Laravel Breezeroutes/auth.php 예제 :

Route::get('/', function () {
    return view('welcome');
});

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth'])->name('dashboard');

require __DIR__.'/auth.php';

그런 다음, routes/auth.php :

use App\Http\Controllers\Auth\AuthenticatedSessionController;
use App\Http\Controllers\Auth\RegisteredUserController;
// ... more controllers

use Illuminate\Support\Facades\Route;

Route::get('/register', [RegisteredUserController::class, 'create'])
                ->middleware('guest')
                ->name('register');

Route::post('/register', [RegisteredUserController::class, 'store'])
                ->middleware('guest');

// ... A dozen more routes

하지만 이 include()는 별도의 라우트 파일에 접두사 / 미들웨어에 대해 동일한 설정일 경우에만 사용해야합니다. 그렇지 않으면 app/Providers/RouteServiceProvider에서 그룹화하는 것이 좋습니다.

public function boot()
{
    $this->configureRateLimiting();

    $this->routes(function () {
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));

        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));

        // ... Your routes file listed next here
    });
}

리소스 동사 번역

리소스 컨트롤러를 사용하지만 SEO 목적으로 URL 동사를 영어가 아닌 것으로 변경하려는 경우 /create 대신 스페인어 /crear 를 원하면 App\Providers\RouteServiceProvider Route::resourceVerbs() 메서드를 사용하여 변경 할 수 있습니다.

public function boot()
{
    Route::resourceVerbs([
        'create' => 'crear',
        'edit' => 'editar',
    ]);

    // ...
}

사용자 지정 리소스 경로 이름

리소스 컨트롤러를 사용할 때 routes/web.php 에서 ->names() 매개 변수를 지정할 수 있으므로 브라우저의 URL 접두사와 Laravel 프로젝트 전체에서 사용하는 경로 이름 접두사가 다를 수 있습니다.

Route::resource('p', ProductController::class)->names('products');

따라서 위의 코드는 /p , /p/{id} , /p/{id}/edit 등과 같은 URL을 생성합니다.하지만 코드에서 route('products.index') , route('products.create')

더 읽기 쉬운 라우트 목록

"php artisan route : list"를 실행 한 다음 목록이 너무 많은 공간을 차지하고 읽기 어렵다는 것을 깨달은 적이 있습니까?

해결책은 다음과 같습니다 : php artisan route:list --compact

그러면 6 개 열 대신 3 개 열이 표시됩니다. Method / URI / Action 만 표시됩니다.

+----------+---------------------------------+-------------------------------------------------------------------------+
| Method   | URI                             | Action                                                                  |
+----------+---------------------------------+-------------------------------------------------------------------------+
| GET|HEAD | /                               | Closure                                                                 |
| GET|HEAD | api/user                        | Closure                                                                 |
| POST     | confirm-password                | App\Http\Controllers\Auth\ConfirmablePasswordController@store           |
| GET|HEAD | confirm-password                | App\Http\Controllers\Auth\ConfirmablePasswordController@show            |
| GET|HEAD | dashboard                       | Closure                                                                 |
| POST     | email/verification-notification | App\Http\Controllers\Auth\EmailVerificationNotificationController@store |
| POST     | forgot-password                 | App\Http\Controllers\Auth\PasswordResetLinkController@store             |
| GET|HEAD | forgot-password                 | App\Http\Controllers\Auth\PasswordResetLinkController@create            |
| POST     | login                           | App\Http\Controllers\Auth\AuthenticatedSessionController@store          |
| GET|HEAD | login                           | App\Http\Controllers\Auth\AuthenticatedSessionController@create         |
| POST     | logout                          | App\Http\Controllers\Auth\AuthenticatedSessionController@destroy        |
| POST     | register                        | App\Http\Controllers\Auth\RegisteredUserController@store                |
| GET|HEAD | register                        | App\Http\Controllers\Auth\RegisteredUserController@create               |
| POST     | reset-password                  | App\Http\Controllers\Auth\NewPasswordController@store                   |
| GET|HEAD | reset-password/{token}          | App\Http\Controllers\Auth\NewPasswordController@create                  |
| GET|HEAD | verify-email                    | App\Http\Controllers\Auth\EmailVerificationPromptController@__invoke    |
| GET|HEAD | verify-email/{id}/{hash}        | App\Http\Controllers\Auth\VerifyEmailController@__invoke                |
+----------+---------------------------------+-------------------------------------------------------------------------+

원하는 정확한 열을 지정할 수도 있습니다.

php artisan route:list --columns=Method,URI,Name

+----------+---------------------------------+---------------------+
| Method   | URI                             | Name                |
+----------+---------------------------------+---------------------+
| GET|HEAD | /                               |                     |
| GET|HEAD | api/user                        |                     |
| POST     | confirm-password                |                     |
| GET|HEAD | confirm-password                | password.confirm    |
| GET|HEAD | dashboard                       | dashboard           |
| POST     | email/verification-notification | verification.send   |
| POST     | forgot-password                 | password.email      |
| GET|HEAD | forgot-password                 | password.request    |
| POST     | login                           |                     |
| GET|HEAD | login                           | login               |
| POST     | logout                          | logout              |
| POST     | register                        |                     |
| GET|HEAD | register                        | register            |
| POST     | reset-password                  | password.update     |
| GET|HEAD | reset-password/{token}          | password.reset      |
| GET|HEAD | verify-email                    | verification.notice |
| GET|HEAD | verify-email/{id}/{hash}        | verification.verify |
+----------+---------------------------------+---------------------+

유효성 검사

⬆️ 맨 위로 이동 ⬅️ 이전 (라우팅) ➡️ 다음 (컬렉션)

이미지 유효성 검사

업로드 된 이미지의 유효성을 검사하는 동안 필요한 크기를 지정할 수 있습니다.

['photo' => 'dimensions:max_width=4096,max_height=4096']

사용자 지정 유효성 검사 오류 메시지

필드 , 규칙언어 별로 유효성 검사 오류 메시지를 사용자 정의 할 수 있습니다. 적절한 배열 구조로 특정 언어 파일 resources/lang/xx/validation.php 를 생성하기 만하면됩니다.

'custom' => [
     'email' => [
        'required' => 'We need to know your e-mail address!',
     ],
],

"지금"또는 "어제"단어로 날짜 확인

이전 / 이후 규칙에 따라 날짜의 유효성을 검사하고 tomorrow , now , yesterday 와 같은 다양한 문자열을 매개 변수로 전달할 수 있습니다. 예 : 'start_date' => 'after:now' . 내부적으로는 strtotime()을 사용하고 있습니다.

$rules = [
    'start_date' => 'after:tomorrow',
    'end_date' => 'after:start_date'
];

일부 조건이있는 유효성 검사 규칙

유효성 검사 규칙이 일부 조건에 의존하는 경우 FormRequest 클래스에 withValidator() 를 추가하여 규칙을 수정하고 여기에서 사용자 지정 논리를 지정할 수 있습니다. 예를 들어 일부 사용자 역할에 대해서만 유효성 검사 규칙을 추가하려는 경우입니다.

use Illuminate\Validation\Validator;
class StoreBlogCategoryRequest extends FormRequest {
    public function withValidator(Validator $validator) {
        if (auth()->user()->is_admin) {
            $validator->addRules(['some_secret_password' => 'required']);
        }
    }
}

기본 검증 메시지 변경

특정 필드 및 특정 유효성 검사 규칙에 대한 기본 유효성 검사 오류 메시지를 변경하려면 FormRequest 클래스에 messages() 메서드를 추가하면됩니다.

class StoreUserRequest extends FormRequest
{
    public function rules()
    {
        return ['name' => 'required'];
    }

    public function messages()
    {
        return ['name.required' => 'User name should be real name'];
    }
}

검증 준비

기본 Laravel 유효성 검사 전에 일부 필드를 수정하려는 경우, 즉 해당 필드를 "준비"하려면 무엇을 추측해야합니다. 이것을 위한FormRequest 클래스에 prepareForValidation() 메소드가 있습니다.

protected function prepareForValidation()
{
    $this->merge([
        'slug' => Illuminate\Support\Str::slug($this->slug),
    ]);
}

첫 번째 유효성 검사 오류시 중지

기본적으로 Laravel 유효성 검사 오류는 모든 유효성 검사 규칙을 확인하여 목록으로 반환됩니다. 그러나 첫 번째 오류 후에 프로세스를 중지하려면 bail 이라는 유효성 검사 규칙을 사용하십시오.

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

컬렉션

⬆️ 맨 위로 이동 ⬅️ 이전 (검증) ➡️ 다음 (인증)

컬렉션에서 NULL로 필터링하지 마십시오.

Eloquent에서 NULL로 필터링 할 수 있지만 컬렉션을 추가로 필터링하는 경우 빈 문자열로 필터링하면 해당 필드에 더 이상 "null"이 없습니다.

// This works
$messages = Message::where('read_at is null')->get();

// Won’t work - will return 0 messages
$messages = Message::all();
$unread_messages = $messages->where('read_at is null')->count();

// Will work
$unread_messages = $messages->where('read_at', '')->count();

사용자 정의 콜백 함수가있는 콜렉션에서 groupBy 사용

데이터베이스의 직접 열이 아닌 일부 조건에 따라 결과를 그룹화하려면 클로저 기능을 제공하여 수행 할 수 있습니다.

예를 들어, 등록일별로 사용자를 그룹화하려는 경우 코드는 다음과 같습니다.

$users = User::all()->groupBy(function($item) {
    return $item->created_at->format('Y-m-d');
});

⚠️주의 : Collection 클래스에서 수행되므로 데이터베이스에서 결과를 가져온 후에 수행됩니다.

한 행의 여러 수집 방법

->all() 또는 ->get() 모든 결과를 쿼리하면 동일한 결과에 대해 다양한 Collection 작업을 수행 할 수 있으며 매번 데이터베이스를 쿼리하지 않습니다.

$users = User::all();
echo 'Max ID: ' . $users->max('id');
echo 'Average age: ' . $users->avg('age');
echo 'Total budget: ' . $users->sum('budget');

페이이지네이션 합계 계산

PAGINATED 컬렉션 만있는 경우 모든 레코드의 합계를 계산하는 방법은 무엇입니까? 동일한 쿼리에서 페이지네이션 전에 계산을 실행하십시오.

// How to get sum of post_views with pagination?
$posts = Post::paginate(10);
// This will be only for page 1, not ALL posts
$sum = $posts->sum('post_views');

// Do this with Query Builder
$query = Post::query();
// Calculate sum
$sum = $query->sum('post_views');
// And then do the pagination from the same query
$posts = $query->paginate(10);

인증

⬆️ 맨 위로 이동 ⬅️ 이전 (컬렉션) ➡️ 다음 (메일)

한 번에 여러 권한 확인

@can Blade 지시문 외에도 @canany 지시문으로 한 번에 여러 권한을 확인할 수 있다는 것을 알고 계셨습니까?

@canany(['update', 'view', 'delete'], $post)
    // The current user can update, view, or delete the post
@elsecanany(['create'], \App\Post::class)
    // The current user can create a post
@endcanany

사용자 등록에 대한 추가 이벤트

신규 사용자 등록 후 몇 가지 작업을 수행하고 싶으십니까? app/Providers/EventServiceProvider.php 하여 Listeners 클래스를 더 추가 한 다음 해당 클래스에서 $event->user 객체로 handle() 메서드를 구현합니다.

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,

            // You can add any Listener class here
            // With handle() method inside of that class
        ],
    ];

Auth::once()에 대해 알고 계셨습니까?

Auth::once() 메소드를 사용하여 ONE REQUEST에 대해서만 사용자로 로그인 할 수 있습니다. 세션이나 쿠키가 사용되지 않으므로 이 방법은 상태를 저장하지 않는 API를 구축 할 때 유용 할 수 있습니다.

if (Auth::once($credentials)) {
    //
}

사용자 비밀번호 업데이트시 API 토큰 변경

비밀번호가 변경되면 사용자의 API 토큰을 변경하는 것이 편리합니다.

모델:

public function setPasswordAttribute($value)
{
    $this->attributes['password'] = $value;
    $this->attributes['api_token'] = Str::random(100);
}

최고 관리자에 대한 권한 재정의

Gates를 정의했지만 SUPER ADMIN 사용자의 모든 권한을 재정의하려는 경우 해당 superadmin ALL 권한을 부여하려면 AuthServiceProvider.php 파일에서 Gate::before()문을 사용하여 게이트를 가로 챌 수 있습니다.

// Intercept any Gate and check if it's super admin
Gate::before(function($user, $ability) {
    if ($user->is_super_admin == 1) {
        return true;
    }
});

// Or if you use some permissions package...
Gate::before(function($user, $ability) {
    if ($user->hasPermission('root')) {
        return true;
    }
});

메일

⬆️ 맨 위로 이동 ⬅️ 이전 (인증) ➡️ 다음 (Artisan)

laravel.log로 이메일 테스트

앱에서 이메일 콘텐츠를 테스트하고 싶지만 Mailgun과 같은 설정을 할 수 없거나 설정하지 않으려는 경우 .env 매개 변수 MAIL_DRIVER=log 를 사용하면 모든 이메일이 실제로 전송되는 대신 storage/logs/laravel.log 파일에 저장됩니다. .

이메일 미리보기

Mailables를 사용하여 이메일을 보내는 경우 브라우저에서 직접 보내지 않고 결과를 미리 볼 수 있습니다. 경로 결과로 Mailable을 반환하십시오.

Route::get('/mailable', function () {
    $invoice = App\Invoice::find(1);
    return new App\Mail\InvoicePaid($invoice);
});

Laravel 알림의 기본 이메일 제목

Laravel 알림을 보내고 toMail()에 subject를 지정하지 않으면 기본 제목은 알림 클래스 이름 인 CamelCased into Spaces입니다.

따라서 다음과 같은 경우 :

class UserRegistrationEmail extends Notification {
    //
}

그러면 제목이 User Registration Email인 이메일을 받게됩니다.

누구에게나 알림 보내기

$user->notify()를 사용하여 특정 사용자에게뿐만 아니라 Notification::route()을 통해 원하는 모든 사람에게 소위 "주문형" Laravel 알림을 보낼 수 있습니다.

Notification::route('mail', 'taylor@example.com')
        ->route('nexmo', '5555555555')
        ->route('slack', 'https://hooks.slack.com/services/...')
        ->notify(new InvoicePaid($invoice));

Artisan

⬆️ 맨 위로 이동 ⬅️ 이전 (메일) ➡️ 다음 (팩토리)

Artisan 명령 매개 변수

Artisan 명령을 생성 할 때 다양한 방법으로 입력을 요청할 수 있습니다 : $this->confirm() , $this->anticipate() , $this->choice() .

// Yes or no?
if ($this->confirm('Do you wish to continue?')) {
    //
}

// Open question with auto-complete options
$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

// One of the listed options with default index
$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $defaultIndex);

유지보수 모드

유지보수 모드를 활성화하려면 artisan down 명령을 실행하십시오.

php artisan down

그러면 사람들은 기본 503 상태 페이지를 보게됩니다.

라라벨 8에서 플래그를 제공 할 수도 있습니다.

  • 사용자가 리디렉션되어야하는 경로
  • 미리 렌더링되어야하는 뷰
  • 유지 관리 모드를 우회하는 비밀 문구
  • 유지 관리 모드 중 상태 코드
  • X 초마다 페이지 다시로드 재시도
php artisan down --redirect="/" --render="errors::503" --secret="1630542a-246b-4b66-afa1-dd72a4c43515" --status=200 --retry=60

라라벨 8 이전 :

  • 표시 될 메시지
  • X 초마다 페이지 다시로드 재시도
  • 여전히 일부 IP 주소에 대한 액세스 허용
php artisan down --message="Upgrading Database" --retry=60 --allow=127.0.0.1

유지보수 작업을 마쳤으면 다음을 실행하십시오.

php artisan up

Artisan 명령 도움말

artisan 명령의 옵션을 확인하려면 --help 플래그로 artisan 명령을 실행하십시오. 예를 들어, php artisan make:model --help 및 몇 가지 옵션이 있는지 확인하십시오.

Options:
  -a, --all             Generate a migration, seeder, factory, and resource controller for the model
  -c, --controller      Create a new controller for the model
  -f, --factory         Create a new factory for the model
      --force           Create the class even if the model already exists
  -m, --migration       Create a new migration file for the model
  -s, --seed            Create a new seeder file for the model
  -p, --pivot           Indicates if the generated model should be a custom intermediate table model
  -r, --resource        Indicates if the generated controller should be a resource controller
      --api             Indicates if the generated controller should be an API controller
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

정확한 Laravel 버전

php artisan --version 명령을 실행하여 앱에있는 Laravel 버전을 정확히 확인하십시오.

어디서나 Artisan 명령 실행

Artisan 명령의 경우 터미널 뿐만 아니라 Artisan::call() 메서드 사용하여 매개 변수와 함께 코드의 어느 곳에서나 실행할 수 있습니다.

Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
        'user' => 1, '--queue' => 'default'
    ]);

    //
});

팩토리

⬆️ 맨 위로 이동 ⬅️ 이전 (Artisan) ➡️ 다음 (로그 및 디버그)

팩토리 콜백

데이터를 시드하기 위해 팩토리를 사용하는 동안 레코드 삽입 후 일부 작업을 수행하는 팩토리 콜백 기능을 사용 할 수 있습니다.

$factory->afterCreating(App\User::class, function ($user, $faker) {
    $user->accounts()->save(factory(App\Account::class)->make());
});

Seeder / 팩토리로 이미지 생성

Faker가 텍스트 값뿐만 아니라 이미지도 생성 할 수 있다는 것을 알고 계셨습니까? 아래의 avatar 필드를 참고해보세요. 50x50 이미지가 생성됩니다.

$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => bcrypt('password'),
        'remember_token' => Str::random(10),
        'avatar' => $faker->image(storage_path('images'), 50, 50)
    ];
});

로그 및 디버그

⬆️ 맨 위로 이동 ⬅️ 이전 (팩토리) ➡️ 다음 (API)

매개 변수로 로깅

Log::info() 또는 추가 매개 변수가있는 더 짧은 info() 메시지를 작성하여 발생한 상황에 대한 자세한 내용을 볼 수 있습니다.

Log::info('User failed to login.', ['id' => $user->id]);

더 편리한 DD

dd($result) 를 수행하는 대신 Eloquent 문장이나 컬렉션의 끝에 직접 ->dd() 를 메소드로 넣을 수 있습니다.

// 이것 대신
$users = User::where('name', 'Taylor')->get();
dd($users);
// 이렇게 할 수 있습니다
$users = User::where('name', 'Taylor')->get()->dd();

API

⬆️ 맨 위로 이동 ⬅️ 이전 (로그 및 디버그) ➡️ 다음 (기타)

API 리소스 : "데이터"유무?

Eloquent API 리소스를 사용하여 데이터를 반환하면 자동으로 '데이터'에 래핑됩니다. 제거하려면 app/Providers/AppServiceProvider.phpJsonResource::withoutWrapping(); 를 보면 됩니다

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        JsonResource::withoutWrapping();
    }
}

API에서 "모든 것이 정상입니다"를 반환하기

일부 작업을 수행하지만 응답이 없는 API 엔드포인트라서 "모든 것이 정상입니다"만 반환하려는 경우 204 상태 코드 "No content"를 반환 할 수 있습니다. 라라벨에서는 이것을 쉽게 처리할 수 있습니다. return response()->noContent();

public function reorder(Request $request)
{
    foreach ($request->input('rows', []) as $row) {
        Country::find($row['id'])->update(['position' => $row['position']]);
    }

    return response()->noContent();
}

기타

⬆️ 맨 위로 이동 ⬅️ 이전 (API)

.env의 로컬 호스트

.env 파일의 APP_URLhttp://localhost 에서 실제 URL로 변경하는 것을 잊지 마십시오. 이메일 알림 및 다른 곳에 있는 모든 링크의 기반이됩니다.

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:9PHz3TL5C4YrdV6Gg/Xkkmx9btaE93j7rQTUZWm2MqU=
APP_DEBUG=true
APP_URL=http://localhost

"컴포저 업데이트"를 실행할 때 (또는 실행하지 않을 때)

Laravel에 관해 중요한 내용은 아니지만... 프로덕션 라이브 서버에서 composer update 를 실행하지 마십시오. 느리고 저장소가 "깨질"것입니다. 항상 composer update 컴퓨터에서 로컬로 실행하고 새 composer.lock 을 리포지토리에 커밋하고 라이브 서버에서는 composer install 를 실행하십시오.

Composer : 최신 버전 확인

composer.json 패키지 중 어떤 패키지가 최신 버전을 출시했는지 확인하려면 composer outdated 실행하십시오. 다음과 같은 모든 정보가 포함 된 전체 목록이 표시됩니다.

phpdocumentor/type-resolver 0.4.0 0.7.1
phpunit/php-code-coverage   6.1.4 7.0.3 Library that provides collection, processing, and rende...
phpunit/phpunit             7.5.9 8.1.3 The PHP Unit Testing framework.
ralouphie/getallheaders     2.0.5 3.0.3 A polyfill for getallheaders.
sebastian/global-state      2.0.0 3.0.0 Snapshotting of global state

자동 대문자 번역

번역 파일 ( resources/lang )에서 변수를 :variable 로 지정할 수있을 뿐만 아니라 :VARIABLE 또는 :Variable 로 대문자로 지정할 수도 있습니다. 그러면 전달하는 값도 자동으로 대문자로 표시됩니다.

// resources/lang/en/messages.php
'welcome' => 'Welcome, :Name'

// Result: "Welcome, Taylor"
echo __('messages.welcome', ['name' => 'taylor']);

시간만 사용하는 카본(Carbon)

초 또는 분없이 현재 날짜를 보려면 setSeconds(0) 또는 setMinutes(0)과 같은 Carbon의 메서드를 사용하세요.

// 2020-04-20 08:12:34
echo now();

// 2020-04-20 08:12:00
echo now()->setSeconds(0);

// 2020-04-20 08:00:00
echo now()->setSeconds(0)->setMinutes(0);

// Another way - even shorter
echo now()->startOfHour();

단일 액션 컨트롤러

하나의 액션으로 컨트롤러를 만들고 싶다면 __invoke() 메서드를 사용하고 "invokable"컨트롤러를 만들 수도 있습니다.

라우트:

Route::get('user/{id}', 'ShowProfile');

Artisan:

php artisan make:controller ShowProfile --invokable

컨트롤러:

class ShowProfile extends Controller
{
    public function __invoke($id)
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}

특정 컨트롤러 메서드로 이동

URL이나 특정 경로뿐만 아니라 특정 컨트롤러의 특정 메서드로 redirect() 하고 매개 변수를 전달할 수도 있습니다. 이것을 사용하십시오 :

return redirect()->action('SomeController@method', ['param' => $value]);

이전 Laravel 버전 사용

최신 Laravel 대신 OLDER 버전을 사용하려면 다음 명령을 사용하십시오.

composer create-project --prefer-dist laravel/laravel project "7.*"

*를 원하는 버전으로 변경하십시오.

페이지네이션 링크에 매개 변수 추가

기본 페이지네이션 링크에서 추가 매개 변수를 전달하거나 원래 쿼리 문자열을 보존하거나 특정 #xxxxx 앵커를 가리킬 수도 있습니다.

{{ $users->appends(['sort' => 'votes'])->links() }}

{{ $users->withQueryString()->links() }}

{{ $users->fragment('foo')->links() }}

반복 가능한 콜백 함수

여러 번 재사용해야하는 콜백 함수가 있는 경우 변수에 할당 한 다음 다시 사용할 수 있습니다.

$userCondition = function ($query) {
    $query->where('user_id', auth()->id());
};

// 이 사용자의 댓글이 있는 게시글 가져 오기
// 그리고 이 사용자의 댓글 만 반환
$articles = Article::with(['comments' => $userCondition])
    ->whereHas('comments', $userCondition)
    ->get();

리퀘스트 : hasAny

$request->has() 메서드로 하나의 매개 변수를 확인할 수있을 뿐만 아니라 $request->hasAny()를 사용하여 여러 매개 변수가 있는지 확인할 수도 있습니다.

public function store(Request $request)
{
    if ($request->hasAny(['api_key', 'token'])) {
        echo 'We have API key passed';
    } else {
        echo 'No authorization parameter';
    }
}

간단한 페이지네이션

페이지네이션에서 모든 페이지 번호 대신 "이전 / 다음"링크 만 갖고 싶다면 (그리고 그로 인해 DB 쿼리 수가 더 적길 바라면) paginate()대신 simplePaginate() 를 사용하세요.

// Instead of
$users = User::paginate(10);

// You can do this
$users = User::simplePaginate(10);