{"id":15524256,"url":"https://github.com/leocavalcante/dispatch","last_synced_at":"2025-07-08T21:33:34.528Z","repository":{"id":72843939,"uuid":"338461179","full_name":"leocavalcante/dispatch","owner":"leocavalcante","description":"🕊️ Event dispatcher awareness made simple.","archived":false,"fork":false,"pushed_at":"2021-02-13T17:44:58.000Z","size":50,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-26T17:46:38.167Z","etag":null,"topics":["dispatch","event","psr-14"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leocavalcante.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-12T23:54:37.000Z","updated_at":"2023-09-28T07:11:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"a7483c14-c1d1-4745-a7b9-24e5f980dc01","html_url":"https://github.com/leocavalcante/dispatch","commit_stats":{"total_commits":21,"total_committers":1,"mean_commits":21.0,"dds":0.0,"last_synced_commit":"05393a225c88278c7a7ba46e88ec6b3ca38a7057"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leocavalcante/dispatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Fdispatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Fdispatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Fdispatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Fdispatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leocavalcante","download_url":"https://codeload.github.com/leocavalcante/dispatch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Fdispatch/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264353063,"owners_count":23595027,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dispatch","event","psr-14"],"created_at":"2024-10-02T10:50:15.719Z","updated_at":"2025-07-08T21:33:34.503Z","avatar_url":"https://github.com/leocavalcante.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dispatch() [![CI](https://github.com/leocavalcante/dispatch/workflows/CI/badge.svg)](https://github.com/leocavalcante/dispatch/actions) [![Typed](https://shepherd.dev/github/leocavalcante/dispatch/coverage.svg)](https://shepherd.dev/github/leocavalcante/dispatch) [![codecov](https://codecov.io/gh/leocavalcante/dispatch/branch/main/graph/badge.svg?token=RYCLJ6B8QS)](https://codecov.io/gh/leocavalcante/dispatch)\n\n🕊️ Event dispatcher awareness made simple.\n\n## Install\n\n```shell\ncomposer require leocavalcante/dispatch:dev-main\n```\n\n## Usage\n\n### Define a dispatcher\n\nIt can be anyone that implements the [PSR-14 Event Dispatcher Interface](https://www.php-fig.org/psr/psr-14/).\n\n```shell\nuse function Dispatch\\use_dispatcher;\nuse_dispatcher(Psr\\EventDispatcher\\EventDispatcherInterface);\n```\n\n### Then just call `dispatch()`\n\n```shell\nuse function Dispatch\\dispatch;\ndispatch(new MyEvent());\n```\n\nThe idea is exactly to make it able to dispatch events from anywhere in your code avoiding `EventDispatcherInterface` injection boilerplate.\n\n## Example\n\n```php\nuse League\\Event\\EventDispatcher;\nuse function Dispatch\\{dispatch, use_dispatcher};\n\nclass UpperCased {\n    public function __construct(\n        public string $result,\n    ) {}\n}\n\nfunction to_upper(string $str): string {\n    // Do something\n    $upper_case_str = strtoupper($str);\n\n    // And dispatch an Event without EventDispatcherInterface injection boilerplate\n    dispatch(new UpperCased($upper_case_str));\n\n    return $upper_case_str;\n}\n\nclass UpperCauser {\n    public function toUpper(string $str): string {\n        // Do something\n        $upper_case_str = strtoupper($str);\n\n        // And dispatch an Event without EventDispatcherInterface injection boilerplate\n        dispatch(new UpperCased($upper_case_str));\n\n        return $upper_case_str;\n    }\n}\n\n$dispatcher = new EventDispatcher();\n$dispatcher-\u003esubscribeTo(UpperCased::class, static function (UpperCased $event): void {\n    echo \"Some string was upper cased and it is: {$event-\u003eresult}\\n\";\n});\n\nuse_dispatcher($dispatcher);\n\nto_upper('dispatch');\n(new UpperCauser())-\u003etoUpper('rocks!');\n\n// Some string was upper cased and it is: DISPATCH\n// Some string was upper cased and it is: ROCKS!\n```\n\n## Dispatchers\n\nAs said, this is only a small Facade on top of `EventDispatcherInterface` providing namespaced functions to reduce dispatcher injection boilerplate.\n\nYou still need a concrete implementation of an Event Dispatcher, anyone that implements the `EventDispatcherInterface` can be used, but here is a list of a few of them:\n\n- [The PHP League Event](https://event.thephpleague.com/) (my personal favorite, used on tests and examples)\n- [Laminas EventManager](https://docs.laminas.dev/laminas-eventmanager/)\n- [Symfony EventDispatcher](https://symfony.com/doc/current/components/event_dispatcher.html)\n- [Doctrine Event Manager](https://www.doctrine-project.org/projects/event-manager.html)\n- ~~[Événement](https://github.com/igorw/evenement/issues/73)~~\n\n## FAQ\n\n### Does it compromise my tests?\n\n**It shouldn't**. Unless you are testing that your module (class, function, method etc) is dispatching an Event, than it does not interfere the module's behavior.\n\n#### In case you want to test if the module is dispatching an Event.\n\nAnd want to inject your fixture/stub/mock for `EventDispatcherInterface`, you can always just call `use_dispatcher()` in the test code or test setup.\n*The tricky part is that this dispatcher will be used globally all along.*\nBut you can always call `desuse_dispatcher()` from your tests teardown.\n\n### Doesn't it make my module dependency implicit?\n\n**Yes, it does**. You have to think about `dispatch()` as like a PHP core/built-in function and as if event dispatching is a core part of your application. You model your domain on top of it.\n\n**But remember**, it depends on `EventDispatcherInterface` **only**! It is an interface that can receive any concrete implementation **and** is a accepted and consolidated PSR interface.\n\n### Conclusion\n\nTrade-offs you should accept to pay are:\n\n- The extra handling of the global `EventDispatcherInterface` on tests that should be isolated.\n- Vendor lock-in on this project as if it is a superset of PHP, since you will be not injecting interfaces.\n*Unless you create your own `dispatch()` function under the `Dispatch` namespace (that is why this namespace name is so generic).*\n\nIf these are ok to you. **Happy coding!** I'm sure it will make your event-driven apps pleasant to code with reduce boilerplate.\n\n## Inspired by\n\n- [Event Dispatcher Aware](https://event.thephpleague.com/3.0/extra-utilities/event-dispatcher-aware/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleocavalcante%2Fdispatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleocavalcante%2Fdispatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleocavalcante%2Fdispatch/lists"}