improvframework/configuration

一个用于解析键值数组的有观点配置对象。

0.2.1 2016-06-14 18:53 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:14:43 UTC


README

Build Status Dependency Status Code Climate Coverage Status HHVM Status

Improv 框架 - 配置

一个用于解析键值数组的有观点配置对象。

概览

几乎所有应用程序都需要某种运行时配置。通常,这是通过环境变量、XML 或 YML 文件、属性文件等方式完成的。无论机制如何,配置通常在应用程序启动过程中以字符串键值对数组的形式存在。

在许多情况下,多个值需要编码到单个条目中,该条目需要解析并转换为对应用程序有意义的对象。一些值,如多个 IP 地址的单行字符串列表(例如),可能需要提取到相同的数组中,而其他值可能只需转换为本地整数或布尔值。除了原始映射外,每个应用程序可能都需要一套独特的必要转换,这些转换不同于其他任何应用程序。

有时,传入的键值对集合可能包含比应用程序特定“可配置”部分需要的元组多得多。这在 Docker 化的服务中尤为常见,其中有许多环境变量,但只有一些打算影响应用程序的行为;其余的通常用于容器或操作系统级别的指令。应用程序的启动部分可能会接收来自环境的所有键值对,尽管它实际上只关注少数几个。同样,应用程序中可能有组件或子组件也要求定制的配置,但与软件的其他部分无关。在这些情况下,有时可能希望将“配置”对象的范围限制为仅与应用程序的特定部分相关的项目。

《\Improv\Configuration》库旨在简化将键值对解析为对特定应用程序上下文有用的对象的过程,而无需扩展或膨胀配置对象本身。此外,它提供了快速组织相关配置到专用对象的能力,以满足需求。

包安装

使用 Composer(推荐)

composer require improvframework/configuration

手动

每个版本都可以从Github 上的发行页面下载。或者,您可以分叉、克隆并构建包。然后,将其安装到您选择的位置。

此包符合 PSR-4 自动加载标准。

用法

假设有一组环境变量,它们进入环境的方式(Mesos、docker run -e""、docker-compose.yml 等)暂不考虑

APP_DEBUG_ON="0"
APP_DEBUG_VERBOSITY="4"
APP_DB_READ_POOL="mysql://dbname=appname;host=1.1.1.1|mysql://dbname=appname;host=2.2.2.2"
APP_DB_READ_USER="username"
APP_DB_READ_PASS="password"
APP_DB_WRITE_POOL="mysql://dbname=appname;host=2.2.0.0"
APP_DB_WRITE_USER="username"
APP_DB_WRITE_PASS="password"
APP_MAX_LOGIN_ATTEMPTS="3"
APP_WHITELIST_CIDR="123.456.7.8/32|123.456.255/12,"
APP_SOMESERVICE_API_KEY="oJE5Zh1HUATturnZFHgHuYEZk1q30TWkdIQ"
APP_SOMESERVICE_API_SECRET="4vqK8XYZef1KygvHxROhjGRPAhMteHdMD6LD0a"
APP_SOMESERVICE_API_URL="https://api.example.com/v1.5"
NGINX_MAX_BODY_SIZE="4M"
NGINX_SENDFILE="off"
PHPFPM_HEADER_SIZE="4M"
PHPFPM_BUFFER_COUNT="16"
FPM_BUFFER_SIZE="1M"

基本键读取

读取所有配置,进行一些存在性检查,并提取一些元素

$config = new \Improv\Configuration($_ENV);

$config->has('APP_DEBUG_VERBOSITY'); // true
$config->has('SOME_OTHER_KEY');      // false

$config->get('APP_DEBUG_VERBOSITY'); // string(1) "4"
$config->get('PHPFPM_BUFFER_COUNT'); // string(2) "16"

前缀过滤

上述环境变量很好地“命名空间化”,以表示它们在容器内的意图/方向。如果我们的应用程序实际上只关注以 APP_ 为前缀的变量,我们可以在实例化时传递第二个参数来过滤这些变量。请注意,当请求键时,您不再需要指定前缀

$config = new \Improv\Configuration($_ENV, 'APP_');

$config->get('DEBUG_VERBOSITY');     // string(1) "4"
$config->get('APP_DEBUG_VERBOSITY'); // throws InvalidKeyException
$config->get('PHPFPM_BUFFER_COUNT'); // throws InvalidKeyException

这在注册和引用容器内的各种配置以及应用程序中的服务只对某些变量感兴趣时特别有用。

《withPrefix》方法将接受给定的“基本”配置对象,并从中返回一个新的对象,通过在基本对象中的键上应用另一层前缀过滤来应用。

$container['config.app'] = function () {
	return new \Improv\Configuration($_ENV, 'APP_');
};

$container['config.debug'] = function (Container $container) {
    $base = $container->get('config.app');
    return $base->withPrefix('DEBUG_');
};

$container['config.db'] = function (Container $container) {
	$base = $container->get('config.app');
	return $base->withPrefix('DB_');
};

$container['config.api'] = function (Container $container) {
    $base = $container->get('config.app');
    return $base->withPrefix('SOMESERVICE_API_');
};

// ... //

$container['database.read'] = function (Container $container) {
	$dbconfig = $container->get('config.db');
	return new Database(
		$dbconfig->get('READ_POOL'),
		$dbconfig->get('READ_USER'),
		$dbconfig->get('READ_PASS')
	);
};

// ... //

$container['api.service'] = function (Container $container) {
	$apiconfig = $container->get('config.api');
	return new ApiService(
		$apiconfig->get('URL'),
		$apiconfig->get('KEY'),
		$apiconfig->get('SECRET')
	);
};

映射值

从环境中提取的值通常以字符串形式出现,并且可能以某种方式进行编码,例如由管道、分号或逗号分隔的多个值。可能需要将字符串映射到原始类型,如 intbool,并将分隔的字符串分解成数组或对象。这个库支持这种行为。

如果不采取任何操作,值将原样输出。

$config = new \Improv\Configuration($_ENV, 'APP_');

$config->get('DEBUG_ON');           // string(1) "0"
$config->get('DEBUG_VERBOSITY');    // string(1) "4"
$config->get('MAX_LOGIN_ATTEMPTS'); // string(1) "3"
$config->get('APP_WHITELIST_CIDR'); // string(29) "123.456.7.8/32|123.456.255/12"
$config->get('DB_READ_POOL');       // string(71) "mysql://dbname=appname;host=1.1.1.1|mysql://dbname=appname;host=2.2.2.2"

可以使用 map 方法使用内置方法或回调指定翻译。此外,可以同时针对多个键进行相同的映射。

$config = new \Improv\Configuration($_ENV, 'APP_');

// Use the built-in boolean mapper
$config->map('DEBUG_ON')->toBool();

// Assign multiple keys at once, using built-in int mapper
$config->map('DEBUG_VERBOSITY', 'MAX_LOGIN_ATTEMPTS')->toInt();

// Invoke the "using" method to and callback to parse values
$config->map(
	'WHITELIST_CIDR',
	'DB_READ_POOL'
)->using(
	function($val) {
		return explode('|', $val);
	}
);

// Now, all future retrievals from any part of the application
// will spit out the translated value(s)

// ... //

$config->get('DEBUG_ON');           // bool(false)
$config->get('DEBUG_VERBOSITY');    // int(4)
$config->get('MAX_LOGIN_ATTEMPTS'); // int(3)

$config->get('WHITELIST_CIDR');
// array(2) {
//  [0] => string(14) "123.456.7.8/32"
//  [1] => string(14) "123.456.255/12"
// }

可以使用 using 方法接受任何有效的 callable,其签名应接受一个字符串值作为输入。可调用函数可以返回与应用程序相关的任何值 - 原始值或完整的对象。可调用函数也可以是实现了 __invoke($value) 方法的任何类。这使得共享“映射”、注入依赖等成为可能。

class DelimiterMap
{
	private $delimiter;

	public function __construct($delimiter)
	{
		$this->delimiter = $delimiter;
	}

	public function __invoke($value)
	{
		return explode($this->delimiter, $value);
	}
}

// ... //

$config->map('WHITELIST_CIDR')->using(new DelimiterMap('|'));

注意和问题

请注意,这是一个新包,目前处于测试版。请随时提出建议、错误报告或贡献问题。

附加文档

您可以通过运行 API 文档构建目标来生成和查看此包的 API 文档。运行构建目标

运行构建/测试套件

该包广泛使用 Phing 构建工具。

以下是值得注意的构建目标列表,但请随时查看 build.xml 文件以获得更多信息。

默认目标

运行 ./vendor/bin/phing 将执行 build 目标(与执行 ./vendor/bin/phing build 相同)。这执行代码检查、语法检查、运行所有静态分析工具、测试套件,并生成 API 文档。

“完整”打包目标

执行 ./vendor/bin/phing package 将运行所有上述检查,如果通过,则将源代码打包成可传输的文件,其中只包含相关的源代码。

选择单个目标

  • 运行测试
    • ./vendor/bin/phing test
    • ./vendor/bin/phpunit
  • 执行静态分析
    • ./vendor/bin/phing static-analysis
    • 生成的报告在 ./build/output/reports
  • 生成 API 文档
    • ./vendor/bin/phing documentapi
    • 生成的文档在 ./build/docs/api
  • 从源代码构建包
    • ./vendor/bin/phing package
    • 工件在 ./build/output/artifacts

License Latest Stable Version Latest Unstable Version Total Downloads