Как настроить поведение метода, не используя наследование
Как настроить поведение метода, не используя наследование
Действия до или сразу после вызова метода
Если вы хотите сделать что-либо прямо перед или сразу после того, как вызван метод, вы можете соответственно развернуть метод в начале или в конце метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
class CustomMailer
{
// ...
public function send($subject, $message)
{
// развернуть событие перед методом
$event = new BeforeSendMailEvent($subject, $message);
$this->dispatcher->dispatch('mailer.pre_send', $event);
// получить $foo и $bar из события, они могли быть изменены
$subject = $event->getSubject();
$message = $event->getMessage();
// настоящая реализация метода здесь
$ret = ...;
// сделать что-то после метода
$event = new AfterSendMailEvent($ret);
$this->dispatcher->dispatch('mailer.post_send', $event);
return $event->getReturnValue();
}
}
В этом примере, вызываются два события: mailer.pre_send
до выполнения метода,
и mailer.post_send
- после. Каждое из них использует пользовательский класс
события, чтобы передавать информацию слушателям двух событий. Например,
BeforeSendMailEvent
может выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// src/Event/BeforeSendMailEvent.php
namespace App\Event;
use Symfony\Component\EventDispatcher\Event;
class BeforeSendMailEvent extends Event
{
private $subject;
private $message;
public function __construct($subject, $message)
{
$this->subject = $subject;
$this->message = $message;
}
public function getSubject()
{
return $this->subject;
}
public function setSubject($subject)
{
$this->subject = $subject;
}
public function getMessage()
{
return $this->message;
}
public function setMessage($message)
{
$this->message = $message;
}
}
А AfterSendMailEvent
даже так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// src/Event/AfterSendMailEvent.php
namespace App\Event;
use Symfony\Component\EventDispatcher\Event;
class AfterSendMailEvent extends Event
{
private $returnValue;
public function __construct($returnValue)
{
$this->returnValue = $returnValue;
}
public function getReturnValue()
{
return $this->returnValue;
}
public function setReturnValue($returnValue)
{
$this->returnValue = $returnValue;
}
}
Оба события позволяют вам получить некоторую информацию (например, getMessage()
)
и даже изменить её (например, setMessage()
).
Теперь, вы можете создавать подписчик событий, подключающийсяк этому событию. Например,
вы можете слушать событие mailer.post_send
и изменять возвращённое значение метода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// src/EventSubscriber/MailPostSendSubscriber.php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use App\Event\AfterSendMailEvent;
class MailPostSendSubscriber implements EventSubscriberInterface
{
public function onMailerPostSend(AfterSendMailEvent $event)
{
$ret = $event->getReturnValue();
// изменить исходное значение ``$ret``
$event->setReturnValue($ret);
}
public static function getSubscribedEvents()
{
return array(
'mailer.post_send' => 'onMailerPostSend'
);
}
}
Вот и всё! Ваш подписчик должен быть вызван автоматически (или прочтите больше о конфигурации подписчика событий ).