어노테이션

Flexagon은 PHPDoc 태그를 런타임에 읽어 동작을 바꿉니다 (PhpDocUtil).

표준 표기는 snake_case 입니다.

/** @encrypt */
/** @db_auto_timestamp insert|update */
/** @exclude_from_get_array */

태그 이름은 대소문자와 단어 구분자를 가리지 않습니다. 아래는 전부 같은 태그입니다.

@db_auto_timestamp    @DbAutoTimestamp    @DB_AUTO_TIMESTAMP    @dbautotimestamp

태그 값은 대소문자만 무시하고 구분자는 그대로 봅니다 (insert = INSERT, 단 my_value ≠ myvalue).

한 줄 docblock(/** @db_auto_timestamp insert */)과 여러 줄 docblock 모두 값이 정상 인식됩니다.

@db_auto_timestamp

INSERT/UPDATE 시점에 Unix timestamp를 자동으로 채웁니다. BaseModel의 createdAt/updatedAt에 이미 적용되어 있습니다.

/**
 * @var int|null
 * @db_auto_timestamp insert
 */
protected ?int $createdAt = null;

/**
 * @var int|null
 * @db_auto_timestamp insert|update
 */
protected ?int $updatedAt = null;

@encrypt

프로퍼티를 AES-256-CBC로 자동 암복호화합니다. DB에 저장할 때 암호화되고, 조회해서 객체로 매핑할 때 복호화됩니다.

암호문은 base64(버전 || IV || HMAC-SHA256 || 암호문) 형식입니다. IV는 평문에서 키 기반 HMAC으로 만드는 합성 IV라서 같은 평문은 항상 같은 암호문이 되고, 그래서 WHERE col = :COL로 완전 일치 검색을 할 수 있습니다(대신 DB에서 값이 같은 행끼리는 알아볼 수 있습니다). 복호화 전에 HMAC을 hash_equals()로 검증해 변조를 거부합니다. 키는 패스프레이즈에서 hash_hkdf()로 유도하며 암호화용과 인증용을 분리합니다.

/**
 * @var string
 * @encrypt
 */
private string $residentNumber = '';

_Global::$CLASS_PROPERTY_ENCRYPTION_PASSPHRASE를 10자 이상으로 설정해야 하며, 그렇지 않으면 예외가 발생합니다. 해당 컬럼은 암호문을 담을 수 있도록 충분히 크게 잡아야 합니다.

@exclude_from_get_array

게터를 getArray() / getJson() 결과에서 제외합니다. 비밀번호 해시처럼 직렬화하면 안 되는 값에 씁니다.

/**
 * @exclude_from_get_array
 */
public function getPasswordHash(): string { return $this->passwordHash; }

getArray(forceAll: true)로 호출하면 제외 설정을 무시하고 전부 가져옵니다. DAO가 DB에 쓸 때 내부적으로 이 모드를 사용합니다.

전체 목록과 제약 사항, 직접 어노테이션을 만들어 쓰는 방법은 ANNOTATIONS.md 에 정리해 두었습니다.