라라벨 5.8.11 – Date 파사드에 macro 메소드 추가

하 벌써 5.8.13이 나왔던데 뭔 업데이트가 이리 빠른가요.. 여튼 한 박자 늦긴 했지만 5.8.11 에 변경된 사항을 정리해봅니다.

Date 파사드에 macro 메소드 추가

Date::macro('example', function () {
    return 'hello';
});

Date::example(); // hello

위의 예시에서 보듯이 macro 메소드는 런타임에 인스턴스에 메소드를 추가할 수 있게 해줍니다. macro 메소드는 컬렉션에도 있고 리스폰스에도 있다는데 아직 써보진 못했어요. 왜 이 기능을 추가하기로 했는지 궁금해서 PR을 찾아봤는데 별 내용이 없더군요.

다행히 Carbon에 설명이 있어서 용도를 가늠해볼 수 있었습니다. Carbon 문서에서는 설정이나 유저 선호에 따라 날짜를 출력할 때 쓰기 좋다고 이야기하고 있습니다. 아래는 Carbon 문서에 있는 예시입니다. 파리 시간과 프랑스어로 바꾸고 calendar 메소드를 실행한 결과를 출력하도록 formatForUser 메소드를 추가합니다.

<?php
// Let assume you get user settings from the browser or preferences stored in a database
$userTimezone = 'Europe/Paris';
$userLanguage = 'fr_FR';

Carbon::macro('formatForUser', function () use ($userTimezone, $userLanguage) {
    $date = $this->copy()->tz($userTimezone)->locale($userLanguage);

    return $date->calendar(); // or ->isoFormat($customFormat), ->diffForHumans(), etc.
});

// Then let assume you store all your dates/times in UTC (because you definitely should)
$dateString = '2010-01-23 10:00:00'; // Get this from your database or any input

// Then now you can easily display any date in a page/e-mail using those user settings and the chosen format
echo Carbon::parse($dateString, 'UTC')->formatForUser();   // 23/01/2010

덕분에 이른바 Macroable 이라는 특성에 대해 생각해보는 기회가 됐네요. 현재까지 이해한 바로는 기존 클래스를 확장하기엔 불편하고, 헬퍼보다는 더 체계적이고 싶을 때 쓰면 좋은 것 같습니다. 가령 Collection을 확장해서 MyCollection을 만들면 엘로퀀트 ORM도 Collection 대신 MyCollection을 반환하게 손을 대는 등 프레임워크의 여러 부분에 손을 대야 할 것 같아요. 메소드 하나 추가하자고 일이 너무 커져버리니까 이런 경우에 macro라는 컨셉을 쓰나 봅니다. 이 부분은 잘 몰라서 뇌피셜을 쓴 것이니 바로잡아주실 필요가 있으면 댓글 부탁드려요.

5.8.11에 추가된 게 두 가지 더 있지만 그건 다음에 기회되면 다룰께요.

라라벨 5.8.9 – 이벤트 발견 기능 추가

5.8.8 까지는 어떤 이벤트가 발생하면 어떤 리스너가 작동해야하는지 직접 적어줬어야 했습니다. 아래와 같은 식이죠.

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'App\Events\OrderShipped' => [
        'App\Listeners\SendShipmentNotification',
    ],
];

5.8.9 부터 이벤트 발견 기능이 추가되어 이벤트와 리스너의 관계를 직접 등록하는 수고를 덜게 됐습니다.

이벤트 발견 기능은 기본적으로 비활성화 되어 있습니다. 이벤트 발견 기능을 사용하려면 아래와 같이 EventServiceProvidershouldDiscoverEvents 메소드를 오버라이드해야 합니다.

/**
 * Determine if events and listeners should be automatically discovered.
 *
 * @return bool
 */
public function shouldDiscoverEvents()
{
    return true;
}

이벤트 발견 기능을 활성화하면 이벤트 캐시 파일이 있으면 이를 이용하고, 없으면 실시간으로 이벤트를 찾습니다. 실시간으로 리퀘스트를 찾으면 애플리케이션이 느려지기 때문에 되도록 캐시를 사용하는게 좋습니다. artisan event:cache 명령으로 캐시할 수 있습니다.