Skip to content

Eloquent: 직렬화

소개

Laravel을 사용하여 API를 구축할 때 모델과 관계를 배열이나 JSON으로 변환해야 하는 경우가 많습니다. Eloquent에는 이러한 변환을 수행하는 편리한 방법이 포함되어 있으며, 모델의 직렬화된 표현에 포함되는 속성을 제어할 수도 있습니다.

lightbulb

Eloquent 모델 및 컬렉션 JSON 직렬화를 처리하는 더욱 강력한 방법을 원하시면 Eloquent API 리소스에 대한 문서를 확인하십시오.

모델 및 컬렉션 직렬화

배열로 직렬화

모델과 로드된 관계를 배열로 변환하려면 toArray 메서드를 사용해야 합니다. 이 메서드는 재귀적이므로 모든 속성과 모든 관계(관계의 관계 포함)가 배열로 변환됩니다.

use App\Models\User;
 
$user = User::with('roles')->first();
 
return $user->toArray();

attributesToArray 메서드는 모델의 속성을 배열로 변환하는 데 사용할 수 있지만 관계는 변환하지 않습니다.

$user = User::first();
 
return $user->attributesToArray();

컬렉션 인스턴스에서 toArray 메서드를 호출하여 모델의 전체 컬렉션을 배열로 변환할 수도 있습니다.

$users = User::all();
 
return $users->toArray();

JSON으로 직렬화

모델을 JSON으로 변환하려면 toJson 메서드를 사용해야 합니다. toArray와 마찬가지로 toJson 메서드는 재귀적이므로 모든 속성과 관계가 JSON으로 변환됩니다. 또한 PHP에서 지원하는 모든 JSON 인코딩 옵션을 지정할 수도 있습니다.

use App\Models\User;
 
$user = User::find(1);
 
return $user->toJson();
 
return $user->toJson(JSON_PRETTY_PRINT);

또는 모델이나 컬렉션을 문자열로 캐스팅할 수 있으며, 그러면 모델이나 컬렉션에서 toJson 메서드가 자동으로 호출됩니다.

return (string) User::find(1);

모델 및 컬렉션은 문자열로 캐스팅될 때 JSON으로 변환되므로 애플리케이션의 라우트 또는 컨트롤러에서 Eloquent 객체를 직접 반환할 수 있습니다. Laravel은 라우트 또는 컨트롤러에서 반환될 때 Eloquent 모델과 컬렉션을 JSON으로 자동 직렬화합니다.

Route::get('/users', function () {
return User::all();
});

관계

Eloquent 모델이 JSON으로 변환되면 로드된 관계가 JSON 객체의 속성으로 자동 포함됩니다. 또한 Eloquent 관계 메서드는 "카멜 케이스" 메서드 이름을 사용하여 정의되지만 관계의 JSON 속성은 "스네이크 케이스"가 됩니다.

JSON에서 속성 숨기기

모델의 배열 또는 JSON 표현에 포함되는 속성(예: 암호)을 제한하고 싶을 수 있습니다. 이렇게 하려면 모델에 $hidden 속성을 추가합니다. $hidden 속성의 배열에 나열된 속성은 모델의 직렬화된 표현에 포함되지 않습니다.

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* 직렬화에서 숨겨야 하는 속성입니다.
*
* @var array<string>
*/
protected $hidden = ['password'];
}
lightbulb

관계를 숨기려면 Eloquent 모델의 $hidden 속성에 관계의 메서드 이름을 추가하십시오.

또는 visible 속성을 사용하여 모델의 배열 및 JSON 표현에 포함되어야 하는 속성의 "허용 목록"을 정의할 수 있습니다. $visible 배열에 없는 모든 속성은 모델이 배열 또는 JSON으로 변환될 때 숨겨집니다.

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* 배열에서 표시되어야 하는 속성입니다.
*
* @var array
*/
protected $visible = ['first_name', 'last_name'];
}

속성 가시성 임시 수정

특정 모델 인스턴스에서 일반적으로 숨겨진 일부 속성을 표시하려는 경우 makeVisible 메서드를 사용할 수 있습니다. makeVisible 메서드는 모델 인스턴스를 반환합니다.

return $user->makeVisible('attribute')->toArray();

마찬가지로 일반적으로 표시되는 일부 속성을 숨기려면 makeHidden 메서드를 사용할 수 있습니다.

return $user->makeHidden('attribute')->toArray();

표시되거나 숨겨진 모든 속성을 일시적으로 재정의하려는 경우 각각 setVisiblesetHidden 메서드를 사용할 수 있습니다.

return $user->setVisible(['id', 'name'])->toArray();
 
return $user->setHidden(['email', 'password', 'remember_token'])->toArray();

JSON에 값 추가

모델을 배열 또는 JSON으로 변환할 때 데이터베이스에 해당 열이 없는 속성을 추가하고 싶을 수 있습니다. 이렇게 하려면 먼저 값에 대한 접근자를 정의합니다.

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* 사용자가 관리자인지 확인합니다.
*/
protected function isAdmin(): Attribute
{
return new Attribute(
get: fn () => 'yes',
);
}
}

접근자를 모델의 배열 및 JSON 표현에 항상 추가하려면 모델의 appends 속성에 속성 이름을 추가합니다. 접근자의 PHP 메서드가 "카멜 케이스"를 사용하여 정의된 경우에도 속성 이름은 일반적으로 "스네이크 케이스" 직렬화된 표현을 사용하여 참조된다는 점에 유의하십시오.

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* 모델의 배열 형식에 추가할 접근자입니다.
*
* @var array
*/
protected $appends = ['is_admin'];
}

속성이 appends 목록에 추가되면 모델의 배열 및 JSON 표현 모두에 포함됩니다. appends 배열의 속성은 모델에 구성된 visiblehidden 설정도 준수합니다.

런타임 시 추가

런타임 시 append 메서드를 사용하여 추가 속성을 추가하도록 모델 인스턴스에 지시할 수 있습니다. 또는 setAppends 메서드를 사용하여 지정된 모델 인스턴스에 대해 추가된 속성의 전체 배열을 재정의할 수 있습니다.

return $user->append('is_admin')->toArray();
 
return $user->setAppends(['is_admin'])->toArray();

날짜 직렬화

기본 날짜 형식 사용자 정의

serializeDate 메서드를 재정의하여 기본 직렬화 형식을 사용자 정의할 수 있습니다. 이 메서드는 데이터베이스에 저장하기 위해 날짜 형식을 지정하는 방법에 영향을 미치지 않습니다.

/**
* 배열 / JSON 직렬화를 위해 날짜를 준비합니다.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}

속성별 날짜 형식 사용자 정의

모델의 캐스트 선언에서 날짜 형식을 지정하여 개별 Eloquent 날짜 속성의 직렬화 형식을 사용자 정의할 수 있습니다.

protected function casts(): array
{
return [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];
}