承接 fluffy/connector 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

fluffy/connector

Composer 安装命令:

composer require fluffy/connector

包简介

Provides 'Signals and slots' pattern

README 文档

README

Build Status

Connector - "Signals and slots" mechanism for PHP.

This library is inspired by Qt "Signals and slots" mechanism so it's pretty similar.

Signals and slots

Signal 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.

You can react on that signals in some way. For example: answer the call or feed the cat. Your reactions are slots.

There 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.

Installation

Run

$ composer require fluffy/connector

or add dependency to your composer.json file

"require": {
    ...
    "fluffy/connector": "^1.3"
}

Usage

1. Signals

If 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:

<?php

/**
 * @file
 * Contains definition of Logger class.
 */

use Fluffy\Connector\Signal\SignalInterface;
use Fluffy\Connector\Signal\SignalTrait;

/**
 * Class Logger.
 */
class Logger implements SignalInterface {
    use SignalTrait;

    public function log() 
    {
        // Do logging stuff.
        ...

        // Emit signal about successfull logging.
        $this->emit('somethingIsLogged', 'Some useful data');
    }
}

To 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.

2. Slots

Slot it's a usual class method. Let's define a class with a slot.

<?php

/**
 * @file
 * Contains definition of Receiver class.
 */

/**
 * Class Receiver.
 */
class Receiver
{

  public function slotReactOnSignal($dataFromSignal) {
    echo "Received data: $dataFromSignal";
  }

}

3. Connections

For 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.

use Fluffy\Connector\ConnectionManager;

$logger = new Logger();
$receiver = new Receiver();

ConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');

$logger->log();

Since you called ConnectionManager::connect(SignalInterface $sender, $signalName, $receiver, $slotName); method signal and slot are connected. It means that after call $logger->log() 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:

  • One signal to one slot
  • One signal to many slots
  • Many signals to many slots
  • Many signals to one slot

You can also establish multiple connections by calling ConnectionManager::initConnections(array $connections); method:

ConnectionManager::initConnections([
  ...
  [
    'sender' => new Logger(),
    'signal' => 'somethingIsLogged',
    'receiver' => new Receiver(),
    'slot' => 'slotReactOnSignal',
    'type' => ConnectionManager::CONNECTION_PERMANENT,
  ],
  ...
]);

3.1. Connection types

By 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:

use Fluffy\Connector\ConnectionManager;

$logger = new Logger();
$receiver = new Receiver();

ConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal', ConnectionManager::CONNECTION_ONE_TIME);

$logger->log();

// Log once again.
$logger->log();

After second call of Logger::log() nothing will happen because slot will be disconnected from signal after first emission.

3.2. Connection weights

Since 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.

By 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:

use Fluffy\Connector\ConnectionManager;

$logger = new Logger();
$receiver = new Receiver();

// This connection has weight 0 by default.
ConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');

// And this has weight -10.
ConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'anotherSlotReactOnSignal', ConnectionManager::CONNECTION_ONE_TIME, -10);

// Signal 'somethingIsLogged' is emitted here. Since we've explicitly defined
// connections weights `ConnectionManager` will call slots in the next order:
// 1. Slot 'anotherSlotReactOnSignal'.
// 2. Slot 'slotReactOnSignal'.
$logger->log();

4. Disconnect

If you don't want to listen signal anymore just disconnect from it.

ConnectionManager::disconnect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');

You can also disconnect connections by conditions:

  1. Disconnect all receivers from all signals for a given sender.
ConnectionManager::disconnect($logger);
  1. Disconnect all receivers from a given signal of a given sender.
ConnectionManager::disconnect($logger, 'somethingIsLogged');
  1. Disconnect all slots from a given receiver from a given signal of a given sender.
ConnectionManager::disconnect($logger, 'somethingIsLogged', $receiver);

If you want to reset all existing connections call

ConnectionManager::resetAllConnections()

5. Services connections

If 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:

  1. Let's say you have services.yml file with next services:
services:
  service.logger:
    class: \Logger
    arguments: [...]
  service.receiver:
    class: \Receiver
    arguments: [...]
  1. 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:
# Connection name. Can be any string.
test_connection_one:
  # Sender service id from "services.yml" file.
  sender: service.logger
  # Sender's signal.
  signal: somethingIsLogged
  # Receiver service id from "services.yml" file.
  receiver: service.receiver
  # Receiver's slot.
  slot: slotReactOnSignal
  # Connection type. 0 - "permanent". 1 - "one time".
  # You can omit "type" parameter and it will be
  # "permanent" by default.
  type: 0
  # Connection weight. You can omit "weight" parameter and it will be
  # "0" by default.
  weight: 1

  # You can define as many connections as you want.
  ...
  1. Initialize service connections:
// Here you need to pass a yaml string from file and a service container.
// This should be done once somewhere in a front controller of your
// application.
$serviceConnections = ConnectionManager::parseServicesConnections(file_get_contents('services.connections.yml'), $container);
ConnectionManager::initConnections($serviceConnections);
  1. Now yor \Logger service is ready to emit signals and \Receiver service is ready to react on signals:
// Receiver will respond to signal "somethingIsLogged" with a slot defined in "services.connections.yml".
$container->get('service.logger')->emit('somethingIsLogged', 'Signal data');

Tests

Please see tests for more information and use-cases.

In order to run tests type:

$ composer install

$ ./vendor/bin/phpunit

What for?

I just like Qt's signal and slot system and want to bring it into PHP world.

Any advantages?

  • It's lightweight.
  • Depends only on one third party library: symfony/yaml

License

GPLv3. See LICENSE file.

fluffy/connector 适用场景与选型建议

fluffy/connector 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 56 次下载、GitHub Stars 达 18, 最近一次更新时间为 2016 年 07 月 06 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「signal」 「event-emitter」 「slot」 「signal-slot」 「connection-dispatcher」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 fluffy/connector 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 fluffy/connector 我们能提供哪些服务?
定制开发 / 二次开发

基于 fluffy/connector 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 56
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 18
  • 点击次数: 9
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 18
  • Watchers: 2
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: GPLv3
  • 更新时间: 2016-07-06