참고
이 튜토리얼에서는 MongoDB 확장에 있는 MongoDB\ BSON \Persistable 인터페이스를 사용하여 사용자 지정 데이터 유형을 구현하는 방법을 설명합니다. 대신 코덱을 사용하여 비즈니스 로직에서 MongoDB 지속성 로직을 분리하는 것이 좋습니다. 예시 는 코덱 튜토리얼을 참조하세요.
MongoDB PHP 확장 및 라이브러리는 직렬화 및 역직렬화하는 동안 사용자 지정 클래스를 지원 . PHP의 DateTimeImmutable 클래스가 특정 점 과 함께 저장하는 구역 정보를 유지하는 날짜/시간 정보를 저장 하려는 경우 이 예시 이 유용할 수 있습니다.
이 확장 프로그램은 서버 와 통신할 때 객체를 포함한 PHP 변수를 BSON 으로 직렬화하고, 서버 에서 데이터를 수신할 때 BSON 을 다시 PHP 변수로 역직렬화합니다.
MongoDB\ BSON \Persistable 인터페이스를 구현하여 동작에 영향을 줄 수 있습니다. 클래스가 이 인터페이스를 구현하면 직렬화 시 bsonSerialize 메서드가 호출됩니다. 이 메서드는 BSON 으로 변환하고 데이터베이스 에 저장 배열 또는 stdClass 객체 반환하는 역할을 합니다. 해당 데이터는 나중에 데이터베이스 에서 읽을 때 객체 재구성하는 데 사용됩니다.
예시 를 들어 LocalDateTime
클래스를 소개합니다. 이 클래스는 MongoDB\ BSON\UTCDateTime 데이터 유형 과 구역 래핑합니다.
/* Custom document class that stores a UTCDateTime and time zone and also * implements the UTCDateTime interface for portability. */ class LocalDateTime implements \MongoDB\BSON\Persistable, \MongoDB\BSON\UTCDateTimeInterface { private $utc; private $tz; public function __construct($milliseconds = null, \DateTimeZone $timezone = null) { $this->utc = new \MongoDB\BSON\UTCDateTime($milliseconds); if ($timezone === null) { $timezone = new \DateTimeZone(date_default_timezone_get()); } $this->tz = $timezone; }
MongoDB\ BSON\Persistable 인터페이스를 구현하므로 클래스는 bsonSerialize 및 bsonUnserialize 메서드를 구현 해야 합니다.bsonSerialize 메서드에서는 유지해야 하는 두 가지 값, 즉 MongoDB\ BSON\UTCDateTime 객체 로 표시되는 Epoch 이후의 밀리초 단위의 점 과 Olson 구역 식별자가 포함된 문자열이 포함된 배열 반환합니다.
public function bsonSerialize() { return [ 'utc' => $this->utc, 'tz' => $this->tz->getName(), ]; }
확장 프로그램은 문서 에 __pclass
필드 를 추가하고 이를 데이터베이스 에도 저장 합니다. 이 필드 에는 역직렬화 시 확장 프로그램이 저장된 객체 를 다시 만드는 데 사용할 클래스를 알 수 있도록 PHP 클래스 이름이 포함되어 있습니다.
데이터베이스 에서 문서 읽으면 확장 프로그램은 필드 __pclass
있는지 감지한 다음 객체의 원래 상태 복원하는 MongoDB\ BSON \Persistable::bsonUnserialize 메서드를 실행합니다.
아래 코드에서는 utc
및 tz
필드의 데이터가 올바른 시간인지 확인한 다음 두 비공개 속성에 해당 값을 할당합니다.
public function bsonUnserialize(array $data) { if ( ! isset($data['utc']) || ! $data['utc'] instanceof \MongoDB\BSON\UTCDateTime) { throw new Exception('Expected "utc" field to be a UTCDateTime'); } if ( ! isset($data['tz']) || ! is_string($data['tz'])) { throw new Exception('Expected "tz" field to be a string'); } $this->utc = $data['utc']; $this->tz = new \DateTimeZone($data['tz']); }
이 클래스가 MongoDB\ BSON\UTCDateTimeInterface 인터페이스도 구현한다는 것을 알 수 있습니다. 이 인터페이스는 MongoDB\ BSON\UTCDateTime 클래스의 두 가지 비생성자 메서드를 정의합니다.
기존 BSON 클래스를 감싸는 래퍼는 래퍼 객체를 원래 래핑되지 않은 버전과 동일한 컨텍스트에서 사용할 수 있도록 해당 인터페이스(예: MongoDB\ BSON \UTCDateTimeInterface)를 구현 것이좋습니다. 또한 항상 인터페이스(예: MongoDB\ BSON\UTCDateTimeInterface)에 대해 타입 힌트를 사용하고, 구체적인 클래스(예: MongoDB\ BSON\UTCDateTime)에 대해서는 타입 힌트를 사용하지 않는 것이 좋습니다. 이렇게 하면 래핑된 객체가 메서드에 허용되지 않을 수 있습니다.
새로운 toDateTime
메서드에서는 MongoDB\ BSON \UTCDateTime이 일반적으로 반환 값에 사용하는 UTC 구역 대신 현지 시간대 구역 설정하다 DateTime 객체 반환합니다.
public function toDateTime() { return $this->utc->toDateTime()->setTimezone($this->tz); } public function __toString() { return (string) $this->utc; } }
클래스가 정의되었으므로 이제 문서에서 사용할 수 있습니다. 아래 스니펫은 LocalDateTime
객체에서 BSON으로, 그리고 다시 LocalDateTime
로 왕복 이동하는 것을 보여줍니다.
$bson = MongoDB\BSON\Document::fromPHP(['date' => new LocalDateTime]); $document = $bson->toPHP(); var_dump($document); var_dump($document->date->toDateTime());
다음이 출력됩니다.
object(stdClass)#1 (1) { ["date"]=> object(LocalDateTime)#2 (2) { ["utc":"LocalDateTime":private]=> object(MongoDB\BSON\UTCDateTime)#3 (1) { ["milliseconds"]=> string(13) "1533042443716" } ["tz":"LocalDateTime":private]=> object(DateTimeZone)#4 (2) { ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } } } object(DateTime)#5 (3) { ["date"]=> string(26) "2018-07-31 14:07:23.716000" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" }
Olson 시간대 식별자를 별도의 필드에 저장하는 것은 특정 시간대에 따라 날짜 조작, 서식지정 및 쿼리를 허용하는 MongoDB의 애그리게이션 프레임워크 에서도 잘 작동합니다.