PHP

PHP에서 이벤트와 리스너 사용하기

thebasics 2024. 9. 28. 10:00

목차
1. 이벤트 시스템이란 무엇인가?
   - 이벤트 시스템의 개념
   - 이벤트 시스템의 장점
2. Symfony EventDispatcher 사용 예제
   - EventDispatcher 설치 및 설정
   - 이벤트 생성 및 디스패치
   - 리스너 작성 및 등록
3. 코드 예제
4. 결론 및 추가 학습 자료


1. 이벤트 시스템이란 무엇인가?

이벤트 시스템의 개념

이벤트 시스템은 프로그램 내에서 특정 사건(이벤트)이 발생했을 때, 미리 등록된 처리기(리스너)가 그 사건을 처리하는 구조를 말합니다. 이는 비동기 작업 처리, 시스템 확장성, 모듈 간 결합도를 낮추는 데 유용한 패턴입니다.
- 이벤트(Event 시스템에서 발생하는 특정 사건을 의미합니다. 예를 들어, 사용자 등록, 파일 업로드 등이 이벤트로 간주될 수 있습니다.
- 리스너(Listener 특정 이벤트가 발생했을 때 이를 감지하고, 해당 이벤트를 처리하는 코드를 실행하는 객체입니다.

이벤트 시스템의 장점

- 모듈 간 결합도 감소: 이벤트와 리스너 간의 결합도를 낮춰 모듈 간의 의존성을 줄이고, 코드를 보다 유연하게 작성할 수 있습니다.
- 확장성: 새로운 이벤트와 리스너를 쉽게 추가할 수 있어, 시스템 확장이 용이합니다.
- 비동기 처리: 이벤트 시스템을 통해 비동기 작업을 처리할 수 있어, 애플리케이션의 성능을 향상시킬 수 있습니다.


2. Symfony EventDispatcher 사용 예제

EventDispatcher 설치 및 설정

Symfony의 'EventDispatcher' 컴포넌트는 PHP에서 이벤트와 리스너를 관리하는 강력한 도구입니다. Composer를 통해 설치할 수 있습니다.

Composer를 통한 설치:

composer require symfony/event-dispatcher

설치 후, 'EventDispatcher' 클래스를 사용하여 이벤트를 디스패치하고, 리스너를 등록할 수 있습니다.

이벤트 생성 및 디스패치

먼저, 이벤트 클래스를 정의하고, 특정 상황에서 해당 이벤트를 디스패치하는 코드를 작성해 보겠습니다.

이벤트 클래스 정의:

// src/Event/UserRegisteredEvent.php
<?php

use Symfony\Contracts\EventDispatcher\Event;

class UserRegisteredEvent extends Event
{
    public const NAME = 'user.registered';

    protected $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function getUser()
    {
        return $this->user;
    }
}

?>

이 예제에서는 'UserRegisteredEvent' 클래스를 정의하고, 'user.registered'라는 이벤트 이름을 설정했습니다. 이 이벤트는 사용자가 등록되었을 때 발생하며, 사용자 데이터를 전달합니다.

이벤트 디스패치:

이제 이벤트를 디스패치하는 코드를 작성해보겠습니다.

// public/index.php
<?php

require '../vendor/autoload.php';

use Symfony\Component\EventDispatcher\EventDispatcher;
use UserRegisteredEvent;

$dispatcher = new EventDispatcher();

// 사용자 데이터
$user = ['name' => 'John Doe', 'email' => 'john@example.com'];

// 이벤트 생성 및 디스패치
$event = new UserRegisteredEvent($user);
$dispatcher->dispatch($event, UserRegisteredEvent::NAME);

?>

위 코드에서, 'EventDispatcher' 객체를 생성한 후, 사용자 등록 이벤트를 디스패치합니다.

리스너 작성 및 등록

이벤트가 디스패치되면 이를 처리할 리스너를 작성하고, 해당 리스너를 이벤트에 연결해야 합니다.

리스너 클래스 작성:

// src/Listener/WelcomeEmailListener.php
<?php

use UserRegisteredEvent;

class WelcomeEmailListener
{
    public function onUserRegistered(UserRegisteredEvent $event)
    {
        $user = $event->getUser();
        // 이메일 발송 로직
        echo "Welcome email sent to " . $user['email'];
    }
}

?>

'WelcomeEmailListener' 클래스는 사용자가 등록되었을 때 환영 이메일을 발송하는 역할을 합니다.

리스너 등록 및 실행:

// public/index.php
<?php

require '../vendor/autoload.php';

use Symfony\Component\EventDispatcher\EventDispatcher;
use UserRegisteredEvent;
use WelcomeEmailListener;

$dispatcher = new EventDispatcher();

// 리스너 등록
$listener = new WelcomeEmailListener();
$dispatcher->addListener(UserRegisteredEvent::NAME, [$listener, 'onUserRegistered']);

// 사용자 데이터
$user = ['name' => 'John Doe', 'email' => 'john@example.com'];

// 이벤트 생성 및 디스패치
$event = new UserRegisteredEvent($user);
$dispatcher->dispatch($event, UserRegisteredEvent::NAME);

?>

이 코드에서는 'WelcomeEmailListener' 리스너를 이벤트 디스패처에 등록하고, 사용자가 등록될 때 이벤트가 발생하면 리스너가 자동으로 실행되도록 설정합니다.


3. 코드 예제

다음은 Symfony 'EventDispatcher'를 사용하여 이벤트와 리스너를 구현하는 종합적인 예제입니다.

1. 이벤트 클래스:

// src/Event/UserRegisteredEvent.php
<?php

use Symfony\Contracts\EventDispatcher\Event;

class UserRegisteredEvent extends Event
{
    public const NAME = 'user.registered';

    protected $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function getUser()
    {
        return $this->user;
    }
}

?>

2. 리스너 클래스:

// src/Listener/WelcomeEmailListener.php
<?php

use UserRegisteredEvent;

class WelcomeEmailListener
{
    public function onUserRegistered(UserRegisteredEvent $event)
    {
        $user = $event->getUser();
        // 이메일 발송 로직
        echo "Welcome email sent to " . $user['email'];
    }
}

?>

3. 이벤트 디스패처 및 실행:

// public/index.php
<?php

require '../vendor/autoload.php';

use Symfony\Component\EventDispatcher\EventDispatcher;
use UserRegisteredEvent;
use WelcomeEmailListener;

$dispatcher = new EventDispatcher();

// 리스너 등록
$listener = new WelcomeEmailListener();
$dispatcher->addListener(UserRegisteredEvent::NAME, [$listener, 'onUserRegistered']);

// 사용자 데이터
$user = ['name' => 'John Doe', 'email' => 'john@example.com'];

// 이벤트 생성 및 디스패치
$event = new UserRegisteredEvent($user);
$dispatcher->dispatch($event, UserRegisteredEvent::NAME);

?>

코드 분석:
- 첫 번째 예제는 사용자 등록 이벤트를 정의하는 클래스입니다. 이 클래스는 사용자 데이터를 담고 있으며, 이벤트가 발생했을 때 전달됩니다.
- 두 번째 예제는 사용자 등록 이벤트가 발생했을 때 실행될 리스너입니다. 이 리스너는 환영 이메일을 발송하는 역할을 합니다.
- 세 번째 예제는 이벤트 디스패처를 생성하고, 리스너를 등록한 후, 이벤트를 디스패치하여 사용자 등록과 환영 이메일 발송을 처리합니다.


4. 결론 및 추가 학습 자료

이번 글에서는 PHP에서 이벤트와 리스너를 사용하여 시스템을 확장하고 모듈 간 결합도를 낮추는 방법에 대해 알아보았습니다. Symfony 'EventDispatcher' 컴포넌트를 사용하여 간단하고 효과적인 이벤트 시스템을 구현할 수 있었습니다. 이 패턴을 통해 시스템 확장성, 코드 유지보수성, 비동기 작업 처리가 용이해집니다.

추가 학습 자료:
- [Symfony EventDispatcher 공식 문서](https://symfony.com/doc/current/components/event_dispatcher.html Symfony의 EventDispatcher 컴포넌트에 대한 공식 문서입니다.
- [이벤트 주도 아키텍처](https://martinfowler.com/articles/201701-event-driven.html 이벤트 주도 아키텍처에 대한 마틴 파울러의 설명입니다.


이제 이벤트와 리스너를 사용하여 PHP 애플리케이션의 구조를 보다 유연하고 확장 가능하게 만들 수 있습니다. 실습을 통해 이벤트 기반 시스템을 구축하고, 프로젝트에 적용해보세요!

반응형