Windowsで作る - PHPプログラミングの開発環境
このページへのアクセス 今日: 1 / 昨日: 1 総計: 3416
文書の過去の版を表示しています。
編集中
— y2sunlight 2020-06-23
本章は、若干の補足を加筆してはいるものの単にPSRのサイトを翻訳したものに過ぎません。英語が堪能な方は原文をご参照下さい。翻訳に当たっては、基本的に機械翻訳を使い、理解できない部分は独断で意訳しております。拙い訳では御座いますが恥を忍んで投稿しておりますので、ご指摘など御座いましたらコメントを頂ければ幸いです。
関連記事
— // 原文より翻訳 PSR-14: Event Dispatcher 2020-07-21 現在 //
イベントディスパッチは、よくテストされた一般的なメカニズムであり、開発者はロジックをアプリケーションに簡単かつ一貫して注入できます。
このPSRの目的は、イベントベースの拡張とコラボレーションのための共通のメカニズムを確立して、さまざまなアプリケーションとフレームワークとの間でライブラリとコンポーネントをより自由に再利用できるようにすることです。
このドキュメントのキーワード MUST , MUST NOT , REQUIRED , SHALL , SHALL NOT , SHOULD , SHOULD NOT , RECOMMENDED , MAY 及び OPTIONAL は、 RFC 2119で説明されているように解釈して下さい。
MUST
MUST NOT
REQUIRED
SHALL
SHALL NOT
SHOULD
SHOULD NOT
RECOMMENDED
MAY
OPTIONAL
RFC 2119の説明 MUST, REQUIRED, SHALL — 絶対必要 MUST NOT, SHALL NOT — 絶対禁止 SHOULD, RECOMMENDED — 推奨(但し、無視できる特定の正当な理由が存在するかもしれない) SHOULD NOT — 推奨できない(但し、許可できる特定の正当な理由が存在するかもしれない) MAY, OPTIONAL — オプション
イベントをディスパッチし処理するための共通のインターフェースがあると、開発者は、多くのフレームワークや他のライブラリと共通の方法で相互作用できるライブラリを作成できます。
いくつかの例:
イベントは、エミッターとその適切なリスナーとの通信の単位として機能するオブジェクトです。
エミッターに戻りの情報を提供するリスナーのユースケース呼び出しが必要な場合、イベントオブジェクトはで変更可能であることがあります( MAY )。ただし、そのような双方向通信が必要ない場合は、イベントを不変として定義することをお勧めします( RECOMMENDED )。つまり、イベントには変更可能なメソッドを含まないように定義します。
実装者は、同じオブジェクトが全てのリスナーに渡されることを想定する必要があります( MUST )。
イベントオブジェクトは可逆的なシリアル化と逆シリアル化をサポートすることを推奨されます( RECOMMENDED )。しかし、それは必須ではありません( NOT REQUIRED )。即ち、$event == unserialize(serialize($event)) は true を保つべきです( SHOULD )。 オブジェクトは、PHPの Serializable インターフェース、__sleep() または __wakeup() マジックメソッド、または必要に応じて同様の言語機能を活用できます( MAY )。
NOT REQUIRED
$event == unserialize(serialize($event))
Serializable
__sleep()
__wakeup()
停止可能なイベントは、イベントの特殊なケースで、リスナーがさらに呼び出されないようにする追加の方法を含んでいます。これは、StoppableEventInterface を実装することによって示すことができます。
StoppableEventInterface
StoppableEventInterfaceを実装するイベントは、それが表すどんなイベントが完了したときでも isPropagationStopped() から true を返す必要があります( MUST )。それがいつであるかを決定するのは、クラスの実装者次第です。例えば、PSR-7 RequestInterface オブジェクトを対応する ResponseInterface オブジェクトと照合するように要求しているイベントは、リスナーが呼び出す setResponse(ResponseInterface $res) メソッドを持つことができます。これにより isPropagationStopped() が trueを返すようにできます。
isPropagationStopped()
true
RequestInterface
ResponseInterface
setResponse(ResponseInterface $res)
リスナーは、任意のPHP callableです。リスナーは、パラメーターを1つだけ持つ必要があります( MUST )。それは、応答すべきイベントです。リスナーは、そのユースケースに特に関連するように、そのパラメーターにタイプヒントを示すべきです( SHOULD )。つまり、リスナーはインターフェースに対するタイプヒントを示す場合があり( MAY )、それはそのインターフェースを実装するすべてのイベントタイプまたはそのインターフェースの特定の実装と互換性があることを示します。
リスナーの戻り値は void であるべきで( SHOULD )、明示的に戻すタイプヒントがあるべきです( SHOULD )。ディスパッチャーは、リスナーからの戻り値を無視する必要があります( MUST )。
void
リスナーは他のコードにアクションを委任することができます( MAY )。これには、薄いラッパーであるリスナーが含まれていて、それは実際のビジネスロジックを実行するオブジェクトを包んでいます。
リスナーは、cron、キューサーバー、または同様の手法を使用し、二次プロセスによるて後処理のために、イベントから情報をキューに追加する場合があります( MAY )。それを行うために、イベントオブジェクト自体をシリアル化することができます( MAY )。ただし、すべてのイベントオブジェクトが安全にシリアル化できるとは限らないことに注意する必要があります。二次プロセスは、イベントオブジェクトに加えた変更が他のリスナーに伝播しないこと( NOT )を前提とする必要があります( MUST )。
NOT
上記の原文 A Listener MAY enqueue information from the Event for later processing by a secondary process, using cron, a queue server, or similar techniques. It MAY serialize the Event object itself to do so; however, care should be taken that not all Event objects may be safely serializable. A secondary process MUST assume that any changes it makes to an Event object will NOT propagate to other Listeners.
上記の原文
ディスパッチャーは、EventDispatcherInterface を実装するサービスオブジェクトです。それは、ディスパッチされるイベントに対するリスナープロバイダーからリスナーを取得し、そのイベントで各リスナーを呼び出す責任があります。
EventDispatcherInterface
ディスパッチャーは:
停止可能なイベントが渡された場合、ディスパッチャーは:
ディスパッチャーは、リスナープロバイダーから返される全てのリスナーがタイプセーフであると仮定すべきです( SHOULD )。つまり、ディスパッチャーは、$listener($event) を呼び出しても TypeError が生成されないことを仮定すべきです( SHOULD )。
$listener($event)
TypeError
リスナーによってスローされた例外またはエラーは、それ以降のリスナーの実行をブロックする必要があります( MUST )。リスナーによってスローされた例外またはエラーは、エミッターにまで遡って伝播することが許可されていなければなりません( MUST )。
ディスパッチャーは、スローされたオブジェクトをキャッチしてログに記録したり、追加のアクションを実行したりできますが( MAY )、その後は、元の throwable を再スローする必要があります( MUST )。
リスナープロバイダーは、与えられたイベントに対してどのリスナーが関連し、どのリスナーを呼び出すべきかを決定することに責任があるサービスオブジェクトです。それは、関連するリスナーと、選択した手段によるそれらリスナーを返すべき順序、の両方を決定するかもしれません。それには以下の場合が含まれています( MAY ):
上記の任意の組み合わせ、または他のメカニズムが、必要に応じて使用できます( MAY )。
リスナープロバイダーは、イベントのクラス名を使用して、そのイベントと他のイベントを区別すべきです( SHOULD )。それらはまた、必要に応じて、イベントに関するその他の情報を考慮することもできます( MAY )。
リスナープロバイダーは、リスナーの適用性を決定するときに、親のタイプをイベント自体のタイプと同じように取り扱う必要があります( MUST )。次の場合:
class A {} class B extends A {} $b = new B(); function listener(A $event): void {};
リスナープロバイダーは、タイプ互換であるため、他の基準によって妨げられない限り、listener() を $b の適切なリスナーとして取り扱う必要があります( MUST )。
listener()
$b
ディスパッチャーは、関連するリスナーを決定するためにリスナープロバイダーを構成する必要があります( SHOULD )。 リスナープロバイダーをディスパッチャーとは異なるオブジェクトとして実装することをお勧めしますが( RECOMMENDED )、必須ではありません( NOT REQUIRED )。
namespace Psr\EventDispatcher; /** * イベントのディスパッチャを定義します。 */ interface EventDispatcherInterface { /** * 処理するイベントをすべての関連リスナーに提供します。 * * @param object $event * 処理するオブジェクト。 * * @return object * The Event that was passed, now modified by listeners. * 渡されたイベント。リスナーによって変更されました。 */ public function dispatch(object $event); }
namespace Psr\EventDispatcher; /** * Mapper from an event to the listeners that are applicable to that event. * イベントからそのイベントに適用可能なリスナーへのマッパー。 */ interface ListenerProviderInterface { /** * @param object $event * An event for which to return the relevant listeners. * 関連するリスナーを返すイベント。 * @return iterable<callable> * An iterable (array, iterator, or generator) of callables. Each * callable MUST be type-compatible with $event. * 呼び出し可能オブジェクトの反復可能オブジェクト(配列、反復子、またはジェネレーター)。 * 各呼び出し可能オブジェクトは、$eventと型互換でなければなりません( MUST )。 */ public function getListenersForEvent(object $event) : iterable; }
namespace Psr\EventDispatcher; /** * An Event whose processing may be interrupted when the event has been handled. * イベントが処理されたときに処理が中断される可能性があるイベント。 * * A Dispatcher implementation MUST check to determine if an Event * is marked as stopped after each listener is called. If it is then it should * return immediately without calling any further Listeners. * Dispatcher実装は、各リスナーが呼び出された後にイベントが停止済みとしてマークされているかどうかを * 確認する必要があります( MUST )。そうであれば、それ以上リスナーを呼び出さずにすぐに戻る必要が * あります。 */ interface StoppableEventInterface { /** * Is propagation stopped? * 伝播は停止していますか? * * This will typically only be used by the Dispatcher to determine if the * previous listener halted propagation. * これは通常、前のリスナーが伝播を停止したかどうかを判断するためにDispatcherによってのみ * 使用されます。 * * @return bool * True if the Event is complete and no further listeners should be called. * False to continue calling listeners. * イベントが完了し、それ以上リスナーを呼び出さない場合はTrue。 * リスナーの呼び出しを続行する場合はFalse。 */ public function isPropagationStopped() : bool; }