You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal 8自定义服务构造方法参数异常:期望类实例却获数组

Hey there, let’s work through this dependency injection issue you’re stuck on with your Drupal 8 block module — I remember pulling my hair out over similar problems when I was starting out, so I feel your frustration!

That error message ("argument should be an instance of a class, recognised as an array") is a dead giveaway: Drupal is passing your block’s configuration array to the constructor instead of your DateCalculator service instance. Here’s how to fix it step by step:

1. Make sure your block class implements the right interface

Drupal plugins (including blocks) don’t get dependencies injected directly into the constructor unless you tell them to. You need to add ContainerFactoryPluginInterface to your block class — this tells Drupal to use the create() method to inject services instead of calling the constructor directly.

2. Fix your block class’s constructor and add the create() method

Here’s a complete example of how your block class should look (adjust the namespace and block annotation to match your module):

<?php

namespace Drupal\event_countdown\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\event_countdown\DateCalculator;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides an event countdown block.
 *
 * @Block(
 *   id = "event_countdown_block",
 *   admin_label = @Translation("Event Countdown Block"),
 *   category = @Translation("Custom")
 * )
 */
class EventCountdownBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * The date calculator service instance.
   *
   * @var \Drupal\event_countdown\DateCalculator
   */
  protected $dateCalculator;

  /**
   * Constructs a new EventCountdownBlock.
   *
   * Important: Keep the parameter order exactly like this!
   * Drupal passes configuration, plugin ID, and plugin definition first.
   *
   * @param array $configuration
   *   Block configuration array.
   * @param string $plugin_id
   *   The block plugin ID.
   * @param mixed $plugin_definition
   *   The block plugin definition.
   * @param \Drupal\event_countdown\DateCalculator $date_calculator
   *   Your date calculator service.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, DateCalculator $date_calculator) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->dateCalculator = $date_calculator;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    // Pull your service from the Drupal container
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('event_countdown.date_calculator')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    // Now you can use your service in the build method!
    $countdown = $this->dateCalculator->yourCalculationMethod();
    return [
      '#markup' => $this->t('Time remaining: @time', ['@time' => $countdown]),
    ];
  }
}

3. Double-check your event_countdown.services.yml

Your current service definition looks okay, but make sure it’s in your module’s root directory and the namespace for DateCalculator is correct. If your service has its own dependencies (like the datetime service), add them as arguments:

services:
  event_countdown.date_calculator:
    class: Drupal\event_countdown\DateCalculator
    # Uncomment this if your DateCalculator needs other services
    # arguments: ['@datetime.time']

4. Clear Drupal’s cache!

This is the most common gotcha for new Drupal devs. After making these changes, you need to clear Drupal’s cache (either via the UI at /admin/config/development/performance or with Drush: drush cr). Drupal caches service definitions and plugin classes, so it won’t pick up your changes until you clear it.

Why this fixes your error

Before, you probably had a constructor that only expected the DateCalculator instance. Drupal was trying to pass the block’s configuration array to that constructor, hence the "expected class instance, got array" error. By implementing ContainerFactoryPluginInterface and using the create() method, you’re telling Drupal exactly how to inject your service alongside the required block parameters.

Give these steps a try, and let me know if you hit any other snags!

内容的提问来源于stack exchange,提问作者jhacin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:57:17