原文:https://www.drupal.org/node/1787318

最后更新时间2013年6月13日。原文由heyrocker于2012年9月17日创建。
参与原文编辑的有twistor, Sylvain Lecoy, LinL, miro_dietiker

原有的变量必须转换为使用新的配置系统API/存储机制来实现。

指导原则

  1. 在进行转换工作的过程中,每次只转换一个变量。
    • 确定要转换的变量的名称。
    • 在整个Drupal项目源码中搜索该变量名称以确定哪些地方需要修改。
  2. 使用简短准确的状态名称。这些名称总体上可保持原样,除非原本的名称不准确或者某种意义上会引起误解。
  3. 状态系统通过调用Drupal::state()函数进行初始化。使用get(),set() 和 delete()方法来与状态系统进行交互。Drupal::state()函数返回一个状态对象,所以你可以这样使用
    <?php
     $data
    = Drupal::state()->get('my_state_data');
    ?>
  4. 获取数据时,状态系统并没有像变量系统一样可以指定默认值。但是你可以在函数返回FALSE的时候指定一个默认值,用来标记数据不存在。具体用法如下
    <?php
     $state
    = Drupal::state()->get('my_state') ?: 'Nothing there';
    ?>

    注意:如果布尔值FALSE或者整数0是状态变量的合法值,那么这种情况需要特殊处理。

  5. 下面的例子展示了如何把变量转换成状态:

    Drupal 7

    <?php
      variable_set
    ('my_data', 'foo');
     
    $data = variable_get('my_data', 'bar');
     
    variable_del('my_data');
    ?>

    Drupal 8
    <?php
      Drupal
    ::state()->set('my_data', 'foo');
     
    $data = Drupal::state()->get('my_data') ?: 'bar';
     
    Drupal::state()->delete('my_data');
    ?>
  6. 这里变量名称做了改动以显示是哪个模块创建了该变量。键值必须与配置系统使用相同的名字空间策略。如下所示:
    • cron_last应改为 system.cron_last
    • node_cron_last应改为 node.cron_last
    • menu_masks应改为 menu.masks
  7. 升级的方式应由变量本身的特性决定。如果变量值在从Drupal 7到8的升级过程中保持一致,那么该变量必须在升级时迁移到Drupal 8。示例如下:
    <?php
    /**
     * 把install_task及install_time变量迁移至状态API。
     *
     * @ingroup state_upgrade
     */
    function system_update_8022() {
     
    update_variables_to_state(array(
       
    'install_task' => 'system.install_task',
       
    'install_time' => 'system.install_time',
      ));
    }
    ?>

    然而如果变量值会在缓存清理过程中被重建或自然地在升级过程中被重建,那么这些Drupal 7的变量应被删除。示例如下:

    <?php
    /**
     * 删除drupal_js_cache_files变量。
     *
     * @ingroup state_upgrade
     */
    function system_update_8023() {
     
    update_variable_del('drupal_js_cache_files');
    }
    ?>
  8. 卸载时删除状态:
    /core/modules/comment/comment.install
    <?php
    function comment_uninstall() {
    ...
     
    // 删除状态。
     
    Drupal::state()->delete('comment.node_comment_statistics_scale');
     }
    ?>
  9. 为升级测试添加测试覆盖:
    为升级测试预先填充测试数据
    /core/modules/system/tests/upgrade/drupal-7.state.system.database.php
    <?php
    db_merge
    ('variable')
      ->
    key(array('name' => 'node_cron_comments_scale'))
      ->
    fields(array('value' => serialize(1.0 / 1000)))
      ->
    execute();
    ?>

    检查新的值是否已生效
    /core/modules/system/lib/Drupal/system/Tests/Upgrade/StateSystemUpgradePathTest.php
    <?php
        $expected_state
    ['comment.count_scale'] = array(
         
    'value' => 1.0 / 1000,
         
    'variable_name' => 'node_cron_comments_scale',
        );
    ?>