phine / observer
一个实现了观察者模式的PHP库。
Requires
- php: >=5.3.9
- phine/exception: ~1.0
Requires (Dev)
- league/phpunit-coverage-listener: ~1.0
- phine/test: ~1.0
This package is not auto-updated.
Last update: 2021-12-07 01:41:42 UTC
README
一个实现了观察者模式的PHP库。
摘要
此库提供了观察者模式的一个实现。您可以使用它来创建其他库,例如事件管理器、状态机、MVC框架,甚至为应用提供插件系统。
要求
- PHP >= 5.3.9
- Phine 异常 >= 1.0.0
安装
通过 Composer
$ composer require "phine/observer=~2.0"
使用方法
要创建主题,您需要创建自己的 SubjectInterface
实现,或者使用捆绑的 Subject
类。
use Phine\Observer\Subject; $subject = new Subject();
观察
然后您需要创建自己的 ObserverInterface
实现来观察对主题所做的更改。您可以使用多个观察者实现实例,甚至相同的实例多次。
use Phine\Observer\ObserverInterface; use Phine\Observer\SubjectInterface; // register a few instances $subject->registerObserver(new Message('First')); $subject->registerObserver(new Message('Second')); // register the same one twice $reuse = new Message('Third'); $subject->registerObserver($reuse); $subject->registerObserver($reuse); // notify all observers of an update $subject->notifyObservers(); /** * Simply echos a message when updated. */ class Message implements ObserverInterface { /** * The message to echo. * * @var string */ private $message; /** * Sets the message to echo on update. * * @param string $message The message. */ public function __construct($message) { $this->message = $message; } /** * {@inheritDoc} */ public function receiveUpdate(SubjectInterface $subject) { echo $this->message, "\n"; } }
根据上面的例子,您可以期待以下输出
First
Second
Third
Third
优先级排序观察者
SubjectInterface
的实现支持在注册时对观察者进行优先级排序(registerObserver()
)。默认情况下,如所有示例所示,优先级为 SubjectInterface::FIRST_PRIORITY
(即 0
,零)。但是,您可以指定自己的优先级
$subject->registerObserver(new Message('A'), SubjectInterface::LAST_PRIORITY); $subject->registerObserver(new Message('B'), 789); $subject->registerObserver(new Message('C'), 123); $subject->registerObserver(new Message('D'), 456); $subject->registerObserver(new Message('E'), SubjectInterface::FIRST_PRIORITY);
根据上面的例子,您可以期待以下输出
E
C
D
B
A
当主题更新其观察者时,它从优先级 0
(零)开始,逐级到 PHP_INT_MAX
(最低可能的优先级)。如果使用相同提供者注册了多个观察者,它们将按注册顺序更新。
中断更新
当主题正在更新其注册的观察者时,观察者可以中断主题。观察者通过调用 SubjectInterface::interruptUpdate()
方法来执行中断。
use Phine\Observer\Exception\ReasonException; /** * Simply interrupts the subject in the middle of an update. */ class InterruptingCow implements ObserverInterface { /** * Interrupts the update. */ public function receiveUpdate(SubjectInterface $subject) { // do some work $subject->interruptUpdate( new ReasonException('MOOOOO') ); // do some final work } }
使用以下示例
// create a new subject $subject = new Subject(); // register some observers $subject->registerObserver(new Message('So what did the interrupt cow say?')); $subject->registerObserver(new InterruptingCow()); $subject->registerObserver(new Message('We never get this far.')); // notify the observers $subject->notifyObservers();
您可以期待以下输出
So what did the interrupting cow say?
PHP Fatal error: Uncaught exception '[...]' with message 'MOOOOO' [...]
[...]
观察者不需要提供原因(ReasonException
实例),但如果提供了,将肯定有助于调试过程。
主题集合
有时您可能需要管理一组主题。此库提供了两种方法:Collection
和 ArrayCollection
。Collection
将单个主题与特定的唯一标识符关联。
use Phine\Observer\Collection; // create a new collection $collection = new Collection(); // register a few subjects $collection->registerSubject('one', new Subject()); $collection->registerSubject('two', new Subject()); $collection->registerSubject('three', new Subject());
然后您可以按需检索或替换主题。
// replace one $collection->registerSubject('two', new Subject()); // update observers of another $collection->getSubject('three')->notifyObservers();
ArrayCollection
类提供了一种更简洁的方式来管理主题注册。它是 Collection
类的扩展,支持通过 ArrayCollectionInterface
进行数组访问。
use Phine\Observer\ArrayCollection; // create a new collection $collection = new ArrayCollection(); // register a few subjects $collection['one'] = new Subject(); $collection['two'] = new Subject(); $collection['three'] = new Subject();
与常规的Collection
类一样,您也可以替换和检索单个主题。
// replace one $collection['two'] = new Subject(); // update observers of another $collection['three']->notifyObservers();
文档
您可以在以下位置找到API文档。
许可证
此库可在MIT许可证下使用。