Drupal 8 模块开发 8.2 : 服务和控制器

蒲公英 提交于 周四, 08/17/2017 - 16:41
Drupal8模块开发

原文地址:
https://docs.acquia.com/articles/drupal-8-services-and-controllers  
 

创建个控制器

我们已经创建了控制器,现在把服务追加进去。当 simple_example() 函数被调用时它会返回一个渲染数组。扩展基类总是个好办法。本例中我们的控制器扩展 ControllerBase 类。我们很快就会看到,这使我们能够访问服务。

下载文件

<?php
 
/**
 * @file
 * Contains \Drupal\service_example\ServiceExampleController.
 */
 
namespace Drupal\service_example\Controller;
 
use Drupal\Core\Controller\ControllerBase;
 
class ServiceExampleController extends ControllerBase {
  /**
   * {@inheritdoc}
   */
  public function __construct() {
  }
 
  /**
   * {@inheritdoc}
   */
  public static function create() {
    return new static(
    );
  }
 
  public function simple_example() {
    return [
      '#markup' => 'Hello World'
    ];
  }
}

向控制器追加服务
为了使服务生效,我们使用叫做依赖注入(dependency injection)的一种模式。当我们的对象被创建时,create() 函数被调用。create() 函数然后调 __construct() 函数。在对象被创建之后,simple_example() 函数被调用。Drupal 8 里,大多数控制器的 create() 函数会带有一个容器参数。简而言之,这个容器叫你可以访问服务。更多信息在之后课程里会涉及。create() 函数使用那个容器参数获得服务,并把服务传递给 __construct() 函数,之后 __construct() 会把服务存储为类变量。  

如果听起来复杂的话,那么我们重新梳理下,追加一个服务的基本方法是这样:

  1. 在控制器内使用 create() 函数返回服务。
  2. 传递这个服务到 __construct() 函数。
  3. 把服务作为类变量存储起来。
public static function create(ContainerInterface $container) {
  return new static(
    $container->get('service_example.example_service')
  );
}

象我们提及的那样,create() 函数有一个 ContainerInterface 类型的参数。它有一个重要的函数 get(),我们用它得到服务对象。返回 new static() 本质上调用 __construct() 函数。现在我们只有一个参数,但你可以使用逗号分割的参数列表传递多个服务。

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

这个函数把传递过来的服务存储为一个变量。

/**
* @var \Drupal\service_example\ServiceExampleService
*/
protected $serviceExampleService;

现在我们创建一个新的变量。使用额外的 class 类型,我们使用 use 描述符把他们声明在文件顶部。

use Drupal\service_example\ServiceExampleService;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

现在我们可以在 simple_example() 函数内使用服务的 getServiceExampleValue() 方法了。

public function simple_example() {
  return [
    '#markup' => $this->serviceExampleService->getServiceExampleValue()
  ];
}

最终的 ServiceExampleController.php 文件:

下载文件

<?php
 
/**
 * @file
 * Contains \Drupal\service_example\ServiceExampleController.
 */
 
namespace Drupal\service_example\Controller;
 
use Drupal\service_example\ServiceExampleService;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
 
class ServiceExampleController extends ControllerBase {
 
  /**
   * @var \Drupal\service_example\ServiceExampleService
   */
  protected $serviceExampleService;
 
  /**
   * {@inheritdoc}
   */
  public function __construct(ServiceExampleService $serviceExampleService) {
    $this->serviceExampleService = $serviceExampleService;
  }
 
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('service_example.example_service')
    );
  }
 
  public function simple_example() {
    return [
      '#markup' => $this->serviceExampleService->getServiceExampleValue()
    ];
  }
 
}

现在可以激活这个模块,看下 /examples/service-example/simple 的效果。