{"id":20674626,"url":"https://github.com/pavelloparev/connector","last_synced_at":"2025-06-23T03:40:51.848Z","repository":{"id":56982377,"uuid":"62715683","full_name":"PavelLoparev/connector","owner":"PavelLoparev","description":"Signals and slots are coming into PHP World","archived":false,"fork":false,"pushed_at":"2017-04-09T13:08:22.000Z","size":54,"stargazers_count":18,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-23T07:41:39.058Z","etag":null,"topics":["composer-package","events","php-library","phpunit","signal","slot"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PavelLoparev.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}},"created_at":"2016-07-06T11:24:05.000Z","updated_at":"2025-02-11T13:47:36.000Z","dependencies_parsed_at":"2022-08-21T11:50:44.659Z","dependency_job_id":null,"html_url":"https://github.com/PavelLoparev/connector","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/PavelLoparev/connector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelLoparev%2Fconnector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelLoparev%2Fconnector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelLoparev%2Fconnector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelLoparev%2Fconnector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PavelLoparev","download_url":"https://codeload.github.com/PavelLoparev/connector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PavelLoparev%2Fconnector/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261406782,"owners_count":23153835,"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":["composer-package","events","php-library","phpunit","signal","slot"],"created_at":"2024-11-16T21:06:29.287Z","updated_at":"2025-06-23T03:40:46.822Z","avatar_url":"https://github.com/PavelLoparev.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/PavelLoparev/connector.svg?branch=master)](https://travis-ci.org/PavelLoparev/connector)\n\n# Connector - \"Signals and slots\" mechanism for PHP.\nThis library is inspired by Qt \"Signals and slots\" mechanism so it's pretty similar.\n\n# Signals and slots\nSignal is something that tell outer world about the internal state of an object. For example: phones can ring, cats can meow etc. Rings and meows are signals. They tell us about changing in their internal states.\n\nYou can react on that signals in some way. For example: answer the call or feed the cat. Your reactions are slots.\n\nThere are tha same situations in programming: sometimes we need to react on some changes in object's state. And that's what this library for: it makes communication between objects easier. Even easier than it could be with \"Observer\" pattern.\n\n# Installation\nRun\n```\n$ composer require fluffy/connector\n```\n\nor add dependency to your composer.json file\n\n```javascript\n\"require\": {\n    ...\n    \"fluffy/connector\": \"^1.3\"\n}\n```\n\n# Usage\n\n### 1. Signals\n\nIf you want your object will be able to emit signals you need to implement `SignalInterface` and use `SignalTrait`. For example you have some logger class and you want to emit signal `somethingIsLogged` when logger finished work:\n```php\n\u003c?php\n\n/**\n * @file\n * Contains definition of Logger class.\n */\n\nuse Fluffy\\Connector\\Signal\\SignalInterface;\nuse Fluffy\\Connector\\Signal\\SignalTrait;\n\n/**\n * Class Logger.\n */\nclass Logger implements SignalInterface {\n    use SignalTrait;\n\n    public function log() \n    {\n        // Do logging stuff.\n        ...\n\n        // Emit signal about successfull logging.\n        $this-\u003eemit('somethingIsLogged', 'Some useful data');\n    }\n}\n```\n\nTo emit signal you need to call `emit` method and pass signal name and data. You can pass whatever you want: array, string, object or number. That's all. Now your logger emits signal to outer world. But nobody is connected to this signal yet. Let do this stuff.\n\n### 2. Slots\n\nSlot it's a usual class method. Let's define a class with a slot.\n```php\n\u003c?php\n\n/**\n * @file\n * Contains definition of Receiver class.\n */\n\n/**\n * Class Receiver.\n */\nclass Receiver\n{\n\n  public function slotReactOnSignal($dataFromSignal) {\n    echo \"Received data: $dataFromSignal\";\n  }\n\n}\n\n```\n\n### 3. Connections\n\nFor now we have `Logger` class that emits signal and `Receiver` class with a slot. To react on signal with slot you need to connect them to each other. Let's do it.\n```php\nuse Fluffy\\Connector\\ConnectionManager;\n\n$logger = new Logger();\n$receiver = new Receiver();\n\nConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');\n\n$logger-\u003elog();\n```\n\nSince you called `ConnectionManager::connect(SignalInterface $sender, $signalName, $receiver, $slotName);` method signal and slot are connected. It means that after call `$logger-\u003elog()` the `somethingIsLogged` signal will be emitted and the `slotReactOnSignal` slot will be called. Result will be `\"Received data: Some useful data\"`. You can connect as many slots to signals as you want. Actually you can create connections like:\n\n* One signal to one slot\n* One signal to many slots\n* Many signals to many slots\n* Many signals to one slot\n\nYou can also establish multiple connections by calling `ConnectionManager::initConnections(array $connections);` method:\n```php\nConnectionManager::initConnections([\n  ...\n  [\n    'sender' =\u003e new Logger(),\n    'signal' =\u003e 'somethingIsLogged',\n    'receiver' =\u003e new Receiver(),\n    'slot' =\u003e 'slotReactOnSignal',\n    'type' =\u003e ConnectionManager::CONNECTION_PERMANENT,\n  ],\n  ...\n]);\n```\n\n#### 3.1. Connection types\n\nBy default `ConnectionManager::connect()` method creates permanent connections. It means that slot will not be disconnected from signal after first emission. But you can make one-time connection. Just pass 5th parameter to `ConnectionManager::connect()` method as `ConnectionManager::CONNECTION_ONE_TIME`. For example:\n```php\nuse Fluffy\\Connector\\ConnectionManager;\n\n$logger = new Logger();\n$receiver = new Receiver();\n\nConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal', ConnectionManager::CONNECTION_ONE_TIME);\n\n$logger-\u003elog();\n\n// Log once again.\n$logger-\u003elog();\n```\n\nAfter second call of `Logger::log()` nothing will happen because slot will be disconnected from signal after first emission.\n\n#### 3.2. Connection weights\n\nSince you can connect different receivers with different slots to one sender and signal `ConnectionManager` calls connected slots in a special order - by connections weights. Lower weight has higher priority. Connections weights affect on order of slots from all receivers but not on order of slots inside one receiver.\n\nBy default `ConnectionManager::connect()` method creates permanent connections with zero weight. But you can change it by passing 6th parameter to `ConnectionManager::connect()` method. For example:\n```php\nuse Fluffy\\Connector\\ConnectionManager;\n\n$logger = new Logger();\n$receiver = new Receiver();\n\n// This connection has weight 0 by default.\nConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');\n\n// And this has weight -10.\nConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'anotherSlotReactOnSignal', ConnectionManager::CONNECTION_ONE_TIME, -10);\n\n// Signal 'somethingIsLogged' is emitted here. Since we've explicitly defined\n// connections weights `ConnectionManager` will call slots in the next order:\n// 1. Slot 'anotherSlotReactOnSignal'.\n// 2. Slot 'slotReactOnSignal'.\n$logger-\u003elog();\n```\n\n### 4. Disconnect\n\nIf you don't want to listen signal anymore just disconnect from it.\n```php\nConnectionManager::disconnect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');\n```\n\nYou can also disconnect connections by conditions:\n\n 1. Disconnect all receivers from all signals for a given sender.\n```php\nConnectionManager::disconnect($logger);\n```\n 2. Disconnect all receivers from a given signal of a given sender.\n```php\nConnectionManager::disconnect($logger, 'somethingIsLogged');\n```\n 3. Disconnect all slots from a given receiver from a given signal of a given sender.\n```php\nConnectionManager::disconnect($logger, 'somethingIsLogged', $receiver);\n```\n\nIf you want to reset all existing connections call\n```php\nConnectionManager::resetAllConnections()\n```\n\n### 5. Services connections\n\nIf you are using `Symfony Dependency Injection` component you might don't want to create objects manually but retrieve them from service container instead. For such cases you can connect your services defined in `services.yml` file without any manual object creation. That's how you can achieve this:\n\n1. Let's say you have `services.yml` file with next services:\n```php\nservices:\n  service.logger:\n    class: \\Logger\n    arguments: [...]\n  service.receiver:\n    class: \\Receiver\n    arguments: [...]\n```\n\n2. In order to connect a `\\Receiver` slot `slotReactOnSignal` to a `\\Logger` signal `somethingIsLogged` create a yaml file somewhere (let's say `services.connections.yml`) in you project with next content:\n```yml\n# Connection name. Can be any string.\ntest_connection_one:\n  # Sender service id from \"services.yml\" file.\n  sender: service.logger\n  # Sender's signal.\n  signal: somethingIsLogged\n  # Receiver service id from \"services.yml\" file.\n  receiver: service.receiver\n  # Receiver's slot.\n  slot: slotReactOnSignal\n  # Connection type. 0 - \"permanent\". 1 - \"one time\".\n  # You can omit \"type\" parameter and it will be\n  # \"permanent\" by default.\n  type: 0\n  # Connection weight. You can omit \"weight\" parameter and it will be\n  # \"0\" by default.\n  weight: 1\n\n  # You can define as many connections as you want.\n  ...\n```\n\n3. Initialize service connections:\n```php\n// Here you need to pass a yaml string from file and a service container.\n// This should be done once somewhere in a front controller of your\n// application.\n$serviceConnections = ConnectionManager::parseServicesConnections(file_get_contents('services.connections.yml'), $container);\nConnectionManager::initConnections($serviceConnections);\n```\n\n4. Now yor `\\Logger` service is ready to emit signals and `\\Receiver` service is ready to react on signals:\n```php\n// Receiver will respond to signal \"somethingIsLogged\" with a slot defined in \"services.connections.yml\".\n$container-\u003eget('service.logger')-\u003eemit('somethingIsLogged', 'Signal data');\n```\n\n# Tests\nPlease [see tests](https://github.com/PavelLoparev/connector/blob/master/tests/ConnectorTest.php) for more information and use-cases.\n\nIn order to run tests type:\n\n`$ composer install`\n\n`$ ./vendor/bin/phpunit `\n\n# What for?\nI just like Qt's signal and slot system and want to bring it into PHP world.\n\n# Any advantages?\n* It's lightweight.\n* Depends only on one third party library: `symfony/yaml`\n# License\nGPLv3. See LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavelloparev%2Fconnector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpavelloparev%2Fconnector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavelloparev%2Fconnector/lists"}