Config 组件¶
概览¶
几乎所有应用程序都需要配置数据以保证正常运行。这些配置包括日志文件位置、数据库连接值、注册的服务等参数和初始设置。Phalcon\Config\Config的设计目的是以一种简单、面向对象的方式来存储这些配置数据。
它表示一棵树,其叶节点是配置值。每个Phalcon\Config\Config的子节点都有一个名称,它要么是一个包含配置值的叶子节点,要么是自身为Phalcon\Config\Config实例的子集合,用于保存嵌套值。它提供了访问此类配置集合的方法。每个Phalcon\Config\Config实例代表一个虚拟对象,可以像真实对象属性一样进行遍历。
该类可以直接使用PHP数组实例化,也可以通过读取各种格式的配置文件来实例化,具体方式将在适配器章节中进一步介绍。Phalcon\Config\Config扩展了Phalcon\Support\Collection对象,并继承了它的功能。
<?php
use Phalcon\Config\Config;
$config = new Config(
[
'app' => [
'baseUri' => getenv('APP_BASE_URI'),
'env' => getenv('APP_ENV'),
'name' => getenv('APP_NAME'),
'timezone' => getenv('APP_TIMEZONE'),
'url' => getenv('APP_URL'),
'version' => getenv('VERSION'),
'time' => microtime(true),
],
]
);
echo $config->get('app')->get('name'); // PHALCON
echo $config->app->name; // PHALCON
echo $config->path('app.name'); // PHALCON
工厂¶
newInstance
¶
允许的name
值,对应不同的适配器类有:创建Phalcon\Config\Config
或任何支持的适配器类(Phalcon\Config\Adapter\*
),使用new
类。然而,Phalcon 提供了Phalcon\Config\ConfigFactory
类可以轻松地实例化 config 对象非常简便。调用newInstance
方法时传入name
, fileName
和parameters
数组将返回新的配置对象。
允许的name
值,对应不同的适配器类,如下所示:
名称 | 适配器 |
---|---|
grouped | Phalcon\Config\Adapter\Grouped |
ini | Phalcon\Config\Adapter\Ini |
json | Phalcon\Config\Adapter\Json |
php | Phalcon\Config\Adapter\Php |
yaml | Phalcon\Config\Adapter\Yaml |
例如,创建一个新的PHP 数组作为基础的适配器:
给定一个 PHP 配置文件/app/storage/config.php
<?php
return [
'app' => [
'baseUri' => getenv('APP_BASE_URI'),
'env' => getenv('APP_ENV'),
'name' => getenv('APP_NAME'),
'timezone' => getenv('APP_TIMEZONE'),
'url' => getenv('APP_URL'),
'version' => getenv('VERSION'),
'time' => microtime(true),
],
];
,你可以按如下方式加载:
<?php
use Phalcon\Config\ConfigFactory;
$fileName = '/app/storage/config.php';
$factory = new ConfigFactory();
$config = $factory->newInstance('php', $fileName);
第三个参数newInstance
是一个数组,在这种情况下不是必须的。但是,其他类型的适配器可能会使用它,因此可以根据适配器类型提供相应的参数。关于parameters
数组中可能包含的内容的更多信息,请参阅适配器部分。
load
¶
The Phalcon\Config\ConfigFactory
还提供了load
方法,接受字符串或数组作为参数。如果传递的是字符串,则将其视为要加载的文件的fileName
,并且文件扩展名决定使用的适配器。
<?php
use Phalcon\Config\ConfigFactory;
$fileName = '/app/storage/config.php';
$factory = new ConfigFactory();
$config = $factory->load($fileName);
如果传递的是数组,则必须包含adapter
元素以指定要创建的适配器。此外,filePath
是必需的,用于指定要加载的文件所在的位置。关于数组中可能包含内容的更多信息,请参见适配器部分。
给定一个 INI 配置文件/app/storage/config.ini
超全局变量。如果cookie存在于任一集合中,则返回load
函数将创建一个Ini配置对象:
<?php
use Phalcon\Config\ConfigFactory;
$fileName = '/app/storage/config.ini';
$factory = new ConfigFactory();
$config = $factory->load($fileName);
异常¶
在Phalcon\Config\Config组件中抛出的任何异常类型为Phalcon\Config\Exception。你可以使用此异常选择性地捕获仅从此组件抛出的异常。
php
<?php
use Phalcon\Config\Exception;
use Phalcon\Mvc\Controller;
class IndexController extends Controller
{
public function index()
{
try {
// Get some configuration values
$this->config->database->dbname;
} catch (Exception $ex) {
echo $ex->getMessage();
}
}
}
原生数组¶
The Phalcon\Config\Config组件接受构造函数中的PHP数组并加载它。
<?php
use Phalcon\Config\Config;
$config = new Config(
[
'app' => [
'baseUri' => getenv('APP_BASE_URI'), // '/'
'env' => getenv('APP_ENV'), // 3
'name' => getenv('APP_NAME'), // 'PHALCON'
'timezone' => getenv('APP_TIMEZONE'), // 'UTC'
'url' => getenv('APP_URL'), // 'http://127.0.0.1',
'version' => getenv('VERSION'), // '0.1'
'time' => microtime(true), //
],
]
);
获取¶
魔术方法¶
使用键作为属性(魔术方法)检索数据:
get()
¶
使用get()
方法并链式调用来遍历嵌套对象:
由于Phalcon\Config\Config扩展了Phalcon\Support\Collection,你还可以在get()
中传入第二个参数,当配置项未定义时,将返回该默认值。
路径¶
使用path()
允许方便地获取任意深度的子项。必填参数是一个字符串,表示所请求节点的路径。这个字符串是一个路径名,包含了从第一层开始的每个祖先节点及自身的名称。根节点的路径名为一个空字符串,第一层节点的路径名就是它自己的名称。第二层及以上节点的路径名由其父节点路径名加上分隔符(默认为.
)再加自身的名称组成。
path()
也接受一个defaultValue
参数,若设置了此参数,当配置对象中找不到或未设置该元素时,将返回此值。最后一个参数path()
接受的是路径名中各名称之间的分隔符(必填参数)。
<?php
echo $config->path('app-name', 'default', '-'); // PHALCON
echo $config->path('app-unknown', 'default', '-'); // default
使用getPathDelimiter()
和setPathDelimiter()
方法获取和设置Config 默认使用的分隔符。
函数式编程与path()
结合使用,可用于获取配置数据:
<?php
use Phalcon\Di\Di;
use Phalcon\Config\Config;
/**
* @return mixed|Config
*/
function config() {
$args = func_get_args();
$config = Di::getDefault()->getShared('config');
if (empty($args)) {
return $config;
}
return call_user_func_array(
[$config, 'path'],
$args
);
}
然后你可以这样使用它:
<?php
echo config('app-name', 'default', '-'); // PHALCON
echo config('app-unknown', 'default', '-'); // default
注意
如果你的数据中的键包含特殊字符,比如.
或-
,而你又选择在使用path()
方法时使用相同的字符作为分隔符,那么你将无法得到预期的结果,因为path()
会将分隔符解释为一个新的嵌套层级。
合并¶
有时候我们可能需要合并来自两个不同配置对象的配置数据。例如,我们可能有一个配置对象包含基本/默认设置,而另一个配置对象则加载特定于应用程序运行环境的选项(如测试、开发、生产等)。系统特定的数据可以从.env
文件加载,并通过DotEnv库进行处理。
在上面的场景中,我们需要将第二个配置对象与第一个合并。merge()
允许我们这样做,递归地合并这两个配置对象。
<?php
use Phalcon\Config\Config;
use josegonzalez\Dotenv\Loader;
$baseConfig = new Config(
[
'app' => [
'baseUri' => '/',
'env' => 3,
'name' => 'PHALCON',
'timezone' => 'UTC',
'url' => 'http://127.0.0.1',
'version' => '0.1',
],
]
);
// .env
// APP_NAME='MYAPP'
// APP_TIMEZONE='America/New_York'
$loader = (new josegonzalez\Dotenv\Loader('/app/.env'))
->parse()
->toEnv()
;
$envConfig= new Config(
[
'app' => [
'baseUri' => getenv('APP_BASE_URI'), // '/'
'env' => getenv('APP_ENV'), // 3
'name' => getenv('APP_NAME'), // 'MYAPP'
'timezone' => getenv('APP_TIMEZONE'), // 'America/New_York'
'url' => getenv('APP_URL'), // 'http://127.0.0.1',
'version' => getenv('VERSION'), // '0.1'
'time' => microtime(true), //
],
'logging' => true,
]
);
$baseConfig->merge($envConfig);
echo $baseConfig
->get('app')
->get('name'); // MYAPP
echo $baseConfig
->get('app')
->get('timezone'); // America/New_York
echo $baseConfig
->get('app')
->get('time'); // 1562909409.6162
合并后的对象将是:
Phalcon\Config Object
(
[app] => Phalcon\Config Object
(
[baseUri] => '/',
[env] => 3,
[name] => 'MYAPP',
[timezone] => 'America/New_York',
[url] => 'http://127.0.0.1',
[version] => '0.1',
[time] => microtime(true),
)
[logging] => true
)
是否存在¶
使用has()
你可以判断集合中是否存在某个特定键。
设置¶
该组件还支持set()
这个方法允许你以编程方式添加或修改已加载的数据。
序列化¶
该对象可以通过serialize()
方法序列化并保存到文件或缓存服务中。使用unserialize
方法可以实现反向操作。
toArray
/ toJson
¶
如果你需要将对象转换回数组形式,toArray()
和toJson()
提供了相关方法。
更多信息,请查看 [Phalcon\Support\Collection][support-collection] 文档。
适配器¶
除了核心组件Phalcon\Config\Config设计上可接受字符串(文件名和路径)或原生PHP数组外,还有多个适配器可用。这些适配器有助于读取各种类型的文件以加载配置数据。
可用的适配器¶
类 | 描述 |
---|---|
Phalcon\Config\Adapter\Grouped | 根据相同或不同的适配器加载不同的配置文件。 |
Phalcon\Config\Adapter\Ini | 从 INI 文件中加载配置。内部此适配器使用 PHP 函数parse_ini_file . |
Phalcon\Config\Adapter\Json | 从 JSON 文件中加载配置。需要系统中包含 PHPjson 扩展。 |
Phalcon\Config\Adapter\Php | 从 PHP 多维数组中加载配置。这个适配器提供了最佳性能。 |
Phalcon\Config\Adapter\Yaml | 从 YAML 文件中加载配置。需要系统中包含 PHPyaml 扩展。 |
组合式(Grouped)¶
The Phalcon\Config\Adapter\Grouped适配器允许从多个来源创建一个Phalcon\Config\Config对象,而无需单独创建每个对象。它接受一个带有必要数据的数组配置,默认使用 php 作为默认适配器。
多维数组的构造函数参数包括:
adapter
- 要使用的适配器filePath
- 配置文件的路径
<?php
use Phalcon\Config\Adapter\Grouped;
$options = [
[
'adapter' => 'php',
'filePath' => '/apps/storage/config.php',
],
[
'adapter' => 'ini',
'filePath' => '/apps/storage/database.ini',
'mode' => INI_SCANNER_NORMAL,
],
[
'adapter' => 'json',
'filePath' => '/apps/storage/override.json',
],
];
$config = new Grouped($options);
每个数组元素(表示一个配置文件)设置的键名与各个适配器的构造函数参数相对应。关于所需或可选参数的更多信息,请参阅描述各适配器的相关部分。
你还可以使用array
作为适配器值。如果你选择这样做,则需要使用config
作为第二个键,其值代表你想要加载的配置的实际值。
<?php
use Phalcon\Config\Adapter\Grouped;
$options = [
[
'adapter' => 'php',
'filePath' => '/apps/storage/config.php',
],
[
'adapter' => 'array',
'config' => [
'app' => [
'baseUri' => '/',
'env' => 3,
'name' => 'PHALCON',
'timezone' => 'UTC',
'url' => 'http://127.0.0.1',
'version' => '0.1',
],
],
],
];
$config = new Grouped($options);
最后,一个Phalcon\Config\Config对象也可以作为组合对象的一个选项。
<?php
use Phalcon\Config\Config;
use Phalcon\Config\Adapter\Grouped;
$baseConfig = new Config(
[
'app' => [
'baseUri' => '/',
'env' => 3,
'name' => 'PHALCON',
],
]
);
$options = [
$baseConfig,
[
'adapter' => 'array',
'config' => [
'app' => [
'timezone' => 'UTC',
'url' => 'http://127.0.0.1',
'version' => '0.1',
],
],
],
];
$config = new Grouped($options);
Ini¶
The Phalcon\Config\Adapter\Ini适配器使用优化后的 PHP 函数parse_ini_file来从 INI 文件中读取配置。每个小节代表一个顶层元素,如果键中包含.
分隔符,则子元素会嵌套。默认的扫描方式是INI_SCANNER_RAW
,但可以通过在构造函数中传入不同的模式来覆盖该设置。
示例 INI 文件:
[database]
adapter = Mysql
host = localhost
username = scott
password = cheetah
dbname = test_db
[config]
adapter = ini
filePath = PATH_DATA"storage/config"
mode = 1
[models]
metadata.adapter = 'Memory'
使用方式:
<?php
use Phalcon\Config\Adapter\Ini;
$fileName = '/apps/storage/config.ini';
$mode = INI_SCANNER_NORMAL;
$config = new Ini($fileName, $mode);
echo $config
->get('database')
->get('host'); // localhost
echo $config
->get('models')
->get('metadata')
->get('adapter'); // Memory
当使用Phalcon\Config\ConfigFactory,将模式作为参数设置:
<?php
use Phalcon\Cache\CacheFactory;
$fileName = '/app/storage/config.ini';
$factory = new ConfigFactory();
$options = [
'adapter' => 'ini',
'filePath' => $fileName,
'mode' => INI_SCANNER_NORMAL,
];
$config = $factory->load($options);
或者在使用newInstance()
:
<?php
use Phalcon\Cache\CacheFactory;
$fileName = '/app/storage/config.ini';
$factory = new ConfigFactory();
$params = [
'mode' => INI_SCANNER_NORMAL,
];
$config = $factory->newinstance('ini', $fileName, $params);
Json¶
注意
需要 PHP 的json
扩展存在于系统中
JSON 是一种广泛使用的格式,适用于应用程序之间传输数据以及存储配置数据。Phalcon\Config\Adapter\Json内部使用json_decode()
将 JSON 文件转换为原生 PHP 数组并进行解析。
示例 JSON 文件:
{
"database": {
"adapter": "Mysql",
"host": "localhost",
"username": "scott",
"password": "cheetah",
"dbname": "test_db"
},
"models": {
"metadata": {
"adapter": "Memory"
}
}
}
使用方式:
<?php
use Phalcon\Config\Adapter\Json;
$fileName = '/apps/storage/config.json';
$config = new Json($fileName);
echo $config
->get('database')
->get('host'); // localhost
echo $config
->get('models')
->get('metadata')
->get('adapter'); // Memory
对于Phalcon\Config\ConfigFactory,传入文件名:
<?php
use Phalcon\Cache\CacheFactory;
$fileName = '/app/storage/config.json';
$factory = new ConfigFactory();
$options = [
'adapter' => 'json',
'filePath' => $fileName,
];
$config = $factory->load($options);
或者在使用newInstance()
:
<?php
use Phalcon\Cache\CacheFactory;
$fileName = '/app/storage/config.json';
$factory = new ConfigFactory();
$config = $factory->newinstance('json', $fileName);
Php¶
The Phalcon\Config\Adapter\Php适配器读取一个返回数组的 PHP 文件,并将其加载到Phalcon\Config\Config对象中。配置可以以 PHP 数组的形式存储在一个文件中,适配器将读取并解析它。
示例 PHP 文件:
<?php
return [
'database' => [
'adapter' => 'Mysql',
'host' => 'localhost',
'username' => 'scott',
'password' => 'cheetah',
'dbname' => 'test_db',
],
'models' => [
'metadata' => [
'adapter' => 'Memory',
],
],
];
使用方式:
<?php
use Phalcon\Config\Adapter\Php;
$fileName = '/apps/storage/config.php';
$config = new Php($fileName);
echo $config
->get('database')
->get('host'); // localhost
echo $config
->get('models')
->get('metadata')
->get('adapter'); // Memory
对于Phalcon\Config\ConfigFactory,传入文件名:
<?php
use Phalcon\Cache\CacheFactory;
$fileName = '/app/storage/config.php';
$factory = new ConfigFactory();
$options = [
'adapter' => 'php',
'filePath' => $fileName,
];
$config = $factory->load($options);
或者在使用newInstance()
:
<?php
use Phalcon\Cache\CacheFactory;
$fileName = '/app/storage/config.php';
$factory = new ConfigFactory();
$config = $factory->newinstance('php', $fileName);
Yaml¶
注意
需要系统中存在 PHP 的 yaml 扩展
YAML 是另一种常见的文件格式,Phalcon\Config\Adapter\Yaml需要yaml
PHP 扩展。它使用 PHP 函数yaml_parse_file来读取 YAML 文件。该适配器接受第二个参数 callbacks,作为一个提供 YAML 节点内容处理程序的数组。
示例 YAML 文件:
app:
baseUri: /
env: 3
name: PHALCON
timezone: UTC
url: http://127.0.0.1
version: 0.1
time: 1562960897.712697
models:
metadata:
adapter: Memory
loggers:
handlers:
0:
name: stream
1:
name: redis
使用方式:
<?php
use Phalcon\Config\Adapter\Yaml;
define("APPROOT", dirname(__DIR__));
$fileName = '/apps/storage/config.yml';
$callbacks = [
"!approot" => function($value) {
return APPROOT . $value;
},
];
$config = new Yaml($fileName, $callbacks);
echo $config
->get('database')
->get('host'); // localhost
echo $config
->get('models')
->get('metadata')
->get('adapter'); // Memory
对于Phalcon\Config\ConfigFactory,将模式作为参数设置:
<?php
use Phalcon\Cache\CacheFactory;
define("APPROOT", dirname(__DIR__));
$fileName = '/apps/storage/config.yml';
$factory = new ConfigFactory();
$options = [
'adapter' => 'yaml',
'filePath' => $fileName,
'callbacks' => [
"!approot" => function($value) {
return APPROOT . $value;
},
],
];
$config = $factory->load($options);
或者在使用newInstance()
:
<?php
use Phalcon\Cache\CacheFactory;
define("APPROOT", dirname(__DIR__));
$fileName = '/app/storage/config.yaml';
$factory = new ConfigFactory();
$callbacks = [
"!approot" => function($value) {
return APPROOT . $value;
},
];
$config = $factory->newinstance('yaml', $fileName, $callbacks);
自定义¶
如需更多适配器,请探索Phalcon孵化器.
依赖注入¶
与大多数 Phalcon 组件一样,您可以将Phalcon\Config\Config对象存储在您的Phalcon\Di\Di容器。通过这样做,你可以从控制器、模型、视图以及任何实现Injectable
.
的组件中访问你的配置对象。服务注册和容器访问示例:
<?php
use Phalcon\Di\FactoryDefault;
use Phalcon\Config\Config;
// Create a container
$container = new FactoryDefault();
$container->set(
'config',
function () {
$configData = require 'config/config.php';
return new Config($configData);
}
);
现在可以在控制器中通过config
键访问该组件:
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Config\Config;
/**
* @property Config $config
*/
class MyController extends Controller
{
private function getDatabaseName()
{
return $this->config->database->dbname;
}
}
在视图中也同样适用(Volt 语法)