跳转到内容

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, fileNameparameters数组将返回新的配置对象。

允许的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

[config]
adapter = ini
filePath = PATH_DATA"storage/config"
mode = 1

超全局变量。如果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),         // 
        ],
    ]
);

获取

魔术方法

使用键作为属性(魔术方法)检索数据:

<?php

echo $config->app->name; // PHALCON

get()

使用get()方法并链式调用来遍历嵌套对象:

<?php

echo $config
        ->get('app')
        ->get('name');  // PHALCON

由于Phalcon\Config\Config扩展了Phalcon\Support\Collection,你还可以在get()中传入第二个参数,当配置项未定义时,将返回该默认值。

路径

使用path()允许方便地获取任意深度的子项。必填参数是一个字符串,表示所请求节点的路径。这个字符串是一个路径名,包含了从第一层开始的每个祖先节点及自身的名称。根节点的路径名为一个空字符串,第一层节点的路径名就是它自己的名称。第二层及以上节点的路径名由其父节点路径名加上分隔符(默认为.)再加自身的名称组成。

<?php

echo $config->get('app')->get('name');  // PHALCON

echo $config->path('app.name');  // PHALCON

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需要yamlPHP 扩展。它使用 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 语法)

{{ config.database.dbname }}
无噪 Logo
无噪文档
25 年 6 月翻译
版本号 5.9
文档源↗