logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动
03/10/2025, by Ivan

本页描述了用于获取和设置简单配置数据的 API。(这并不是为存储在 配置对象 中的信息准备的。)

配置数据

每个模块都可以提供默认配置。例如,维护模式的设置定义在 core/modules/system/config/install/system.maintenance.yml 文件中。在这个文件里,第一部分是命名空间,表示哪个模块提供了此配置(本例中的 system 模块),后面是子系统(本例中的 maintenance)。文件 必须 位于 config/install 目录中。同时,它的文件名必须包含“.”符号,以便 ConfigBase->validateName($name) 进行校验。该文件包含如下 YAML:

message: '@site is currently under maintenance. We should be back shortly. Thank you for your patience.'
langcode: en

配置也可以是嵌套的,例如在性能设置中(system.performance.yml):

cache:
  page:
    enabled: '0'
    max_age: '0'
preprocess:
  css: '0'
  js: '0'
response:
  gzip: '0'

重要:根级键必须是映射

配置的根数据必须表示为映射,而不是不可预测的序列。例如,如果您为每个可用实体类型存储数据,请让父级键是实体类型,并添加根键 entity_type。请参见以下示例:

entity_type:
  commerce_order:
    foo: 'bar'
  node:
    foo: 'bar'
  user:
    foo: 'bar'

如果实体类型是根级键,就无法通过 配置架构 来表示配置。此外,当配置作为模块(或主题)安装的一部分时,Drupal 核心也无法添加额外信息。

与配置交互

您通过 Config 对象与这些文件交互,并通过调用 config() 函数来创建 Config 对象实例,该函数的参数是文件名(去掉扩展名)。调用 config 函数会返回一个 \Drupal\Core\Config\ImmutableConfig 实例。

// 不可变配置(只读)。
$config = \Drupal::config('system.performance');
// 可变配置(读/写)。
$config = \Drupal::service('config.factory')->getEditable('system.performance');

一旦您获得了 Config 对象,就可以用多种方式与其交互。

读取配置

使用 get() 方法读取配置。这可以通过几种方式使用。要读取某一项配置,只需指定其键。

$config = \Drupal::config('system.maintenance');
$message = $config->get('message');

\Drupal::config() 调用也可以链式调用。

$message = \Drupal::config('system.maintenance')->get('message');

要读取嵌套配置,请使用“.”来分隔键。

$enabled = \Drupal::config('system.performance')->get('cache.page.enabled');

您可以在任何层级读取配置,只要在该层级下有数组形式的嵌套配置。

$page_cache = \Drupal::config('system.performance')->get('cache.page');

这将返回一个包含两个键的数组——“enabled”和“max_age”。

要返回配置对象中的所有数据,只需调用不带参数的 get() 方法。

您还可以返回系统中所有可用的配置键,或仅返回以某个子字符串(前缀 $)开头的键。

$keys = \Drupal::service('config.factory')->listAll($prefix = "");

写入配置

要修改配置,您需要通过配置工厂调用 getEditable() 来获取 \Drupal\Core\Config\Config 实例(可变配置对象)。尝试修改或调用 \Drupal\Core\Config\ImmutableConfig 的 delete() / save() 方法会触发 ImmutableConfigException 异常。

例如:

\Drupal::service('config.factory')->getEditable('system.performance');

使用 set() 方法修改或添加配置,并通过 save() 方法保存。注意,必须显式保存配置;仅仅将数据写入配置对象不会自动保存。

$config = \Drupal::service('config.factory')->getEditable('system.performance');

// 设置一个标量值。
$config->set('cache.page.enabled', 1);

// 设置一个数组。
$page_cache_data = ['enabled' => 1, 'max_age' => 5];
$config->set('cache.page', $page_cache_data);

// 保存数据到数据库。
$config->save();

set() 方法支持链式调用,因此如果您只需要修改一个值,可以在一行代码中完成。

\Drupal::service('config.factory')->getEditable('system.performance')->set('cache.page.enabled', 1)->save();

如果您想替换配置对象中的所有数据,请使用 setData() 方法。您不能用 setData() 替换数据子集——如果只想替换部分数据,应使用一个或多个 set() 调用。使用 setData() 时,您必须提供完整的键值对,格式与调用不带参数的 get() 返回的关联数组相同。以下是 system.performance.yml 中的示例:

// 设置所有值。
\Drupal::service('config.factory')->getEditable('system.performance')->setData([
    'cache' => [
      'page' => [
        'enabled' => '0',
        'max_age' => '0',
      ],
    ],
    'preprocess' => [
      'css' => '0',
      'js' => '0',
    ],
    'response' => [
      'gzip' => '0',
    ],
  ])
  ->save();

删除配置

可以使用 clear() 函数清除单个配置值,该方法也支持链式调用。

$config = \Drupal::service('config.factory')->getEditable('system.performance');
$config->clear('cache.page.max_age')->save();
$page_cache_data = $config->get('cache.page');

在这个示例中,$page_cache_data 将返回一个只有“enabled”键的数组,因为“max_age”已被清除。

可以使用 delete() 函数删除整个配置集。

\Drupal::service('config.factory')->getEditable('system.performance')->delete();

注意,之后不应再调用 save() 方法,否则会创建一个空的配置集。

最佳实践

避免在同一个函数中多次创建配置对象实例,因为这会降低性能。下面的代码不必要地两次创建了 'foo.bar' 配置对象实例:

\Drupal::service('config.factory')->getEditable('foo.bar')->set('foo', 'foo')->save();
\Drupal::service('config.factory')->getEditable('foo.bar')->set('bar', 'bar')->save();

更好的做法是只创建一次实例,将其保存在变量中,并在剩余代码中复用。

$config = \Drupal::service('config.factory')->getEditable('foo.bar');
$config
  ->set('foo', 'foo')
  ->set('bar', 'bar')
  ->save();

在服务中注入配置值

可以通过服务工厂将配置值注入到自定义服务中。

services:
  app.service:
    class: Drupal/mail_module/Service
    factory: Drupal/mail_module/ServiceFactory:create
    arguments: ['@config.factory']
class ServiceFactory {
  static function create($config) {
    return new Service($config->get('mail.config')->get('transport'));
  }
}

class Service {
  public function __construct($transport) {
    $this->mailTransport = $transport;
  }
}

此示例改编自 如何将配置值注入服务?