定制 dotink/affinity 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

dotink/affinity

Composer 安装命令:

composer require dotink/affinity

包简介

A bootstrapper that loves you

关键字:

README 文档

README

Affinity is a bootstrapper for PHP projects which allows you to create modular configurations and actions that can be dropped into place for added functionality without additional work.

It provides mechanisms for running bootstrap operations and logic as well as creating and accessing well organized configuration data.

Affinity is a key component of the inKWell framework, you can read more about the integration of it at:

http://inkwell.dotink.org/docs/basics/02-nano-core#Bootstrapping

Or... continue reading below for standalone use.

Basic Usage

$engine = new Affinity\Engine(
	new Affinity\NativeDriver('/path/to/configs'),
	new Affinity\NativeDriver('/path/to/actions')
);

$engine->start('production', ['app' => $app, 'di' => $di]);

This example shows the most basic setup of affinity. Using the native driver we can scan directories recursively for configurations or actions to load then call start() in order to execute bootstrapping.

Configuration / Action Directory Structure

The native driver assumes that your configuration and action directory structure looks like the following:

--- config_root [this is what you pass to the __construct() call]
 |
 |- default
 |
 |- environment1
 |
 |- environment2
 |
 |- ...

All configs and actions from default will be included no matter what and will be extended based on the environment provided to the start() call.

You can extend by multiple environments by passing a comma separated list:

$engine->start('production, europe', $context);

This allows you to only override the necessary config data or logic for the specific environment requirements whether they be the execution mode, deployment stability, location, whatever.

The directory structure inside each environment folder is up to you, although it is suggested you use additional sub directories for namespacing purposes.

The relative path to a given config file or action is used by affinity as a means to identify the configuration or action. So, for example config/default/core.php is identified by the simple string 'core' while a file such as include/default/routes/main.php is identified by 'routes/main'.

Configurations

You can create a configuration by returning it from any PHP file located in an environment directory. For example, let's imagine adding the following to config/default/test.php:

return Affinity\Config::create([

	'key' => 'value',

	'parent' => [
		'child' => 'value'
	]
]);

Accessing Configuration Data

Once a config is created, you can access configuration data by using the fetch() method on the affinity engine.

$engine->fetch('test', 'key', 'default');

The parameters for the fetch() method are the configuration id, the parameter within that configuration, and the default value if it's not found, respectively. You can access deeply nested data using a javascript style object notation for the second parameter:

$engine->fetch('test', 'parent.child', 'default');

Aggregate IDs

In addition to identifying a specific configuration to fetch data from, it is also possible to specify types of information which may be provided by multiple configurations using an aggregate ID. All aggregate IDs must begin with @:

$engine->fetch('@providers', 'mapping', array());

In order to provide information for aggregate ID fetches, you need to pass an optional first parameter to the Affinity\Config::create() method containing a list of aggregates you provide. The data is then keyed initially under the aggregate ID within the config itself.

return Affinity\Config::create(['providers'], [
	'@providers' => [
		'mapping' => [
			'Dotink\Package\UsefulInterface' => 'My\Concrete\ProviderClass'
		]
	]
]);

When fetching information from an aggregate ID, the returned array consists of one entry for every configuration file which provides that aggregate data keyed by the specific configuration id. In the case of the above mappings, this means we have to first loop over the individual configuration data, and then over the mapping themselves.

You can fetch a list of specific IDs which provide aggregate data by fetching the aggregate ID alone, without specifying a parameter:

foreach ($engine->fetch('@providers') as $id) {
	$provider_mapping = $engine->fetch($id, '@providers.mapping', []);
	$provider_params  = $engine->fetch($id, '@providers.params',  []);

	foreach ($provider_mapping as $interface => $provider) {
		$injector->alias($interface, $provider);
	}

	foreach ($provider_params as $provider => $params) {
		$injector->define($provider, $params);
	}
}

Actions

Actions are pieces of modularized and pluggable logic which use the configuration data in order to prepare your application for running. Some of their main functions include:

  • Setting up dependency wiring
  • Running static class methods for config or setting static class properties for config
  • Registering providers in the application container

Unlike configs which are just arrays of information, actions represent callable logic.

Creating an Action

Add a file to the appropriate environment and return Affinity\Action::create():

return Affinity\Action::create(function($app, $di) {
	//
	// Your bootstrap logic here
	//
});

Action Ordering (Dependencies)

If you need to make sure your actions run in order, you can add an array of dependencies as an optional first argument. The below action will not run until the action identified by the core ID has run:

return Affinity\Action::create(['core'], function($app, $di) {
	//
	// Your bootstrap logic here
	//
});

Context

In our first example you may have noted the addition of an array which was passed to the start() method on the engine:

$engine->start('production', ['app' => $app, 'di' => $di]);

This is the context. If you didn't pick up on it before, it is provided to the action operations and is also available in the configuration as normal variables. The context can be whatever you want, but is usually used to provide your application instance and dependency injector for use in configs and actions respectively.

dotink/affinity 适用场景与选型建议

dotink/affinity 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.4k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2014 年 03 月 12 日, 在 PHP 生态内属于活跃度较高的组件。

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

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 1.4k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 7
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: AGPL-3.0
  • 更新时间: 2014-03-12