Как получить идентификатор пользователя, который в данный момент вошел в систему?


31

Я хочу получить текущий объект пользователя (информацию о пользователе) в Drupal 8.

Я знаю, что в Drupal 7 была глобальная $userпеременная; Я хочу знать, как я могу получить текущий объект пользователя в Drupal 8.

Ответы:


50
$user = \Drupal::currentUser();

Смотрите Drupalкласс. Есть много вспомогательных методов; большинство из них являются ярлыками для служб, поэтому вам не нужно звонить \Drupal::service()напрямую.

Обратите внимание, что текущий пользователь - это не пользовательский объект, а просто пользовательский прокси. Из него можно получить некоторую базовую информацию, но поля или другая логика, специфичная для сущности, отсутствуют. Чтобы получить доступ к пользовательской сущности, вы должны загрузить ее вручную:

$user = User::load(\Drupal::currentUser()->id());

К сожалению, нет прямого метода, как \Drupal::currentUser()->getEntity():(


20

Пример того, как загрузить текущего пользователя и получить данные поля из объекта пользователя.

<?php
// Load the current user.
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

// retrieve field data from that user
$website = $user->get('field_website')->value;
$body = $user->get('body')->value;


$email = $user->get('mail')->value;
$name = $user->get('name')->value;
$uid= $user->get('uid')->value;
?>

16

Доступ к методам в \Drupalглобальном классе (например ::currentUser()) возможен в процедурном коде (например, в вашем mymodule.moduleфайле), но в вашем собственном ОО-коде вы должны попытаться получить доступ к @current_userслужбе через стандартный шаблон, называемый внедрением зависимости (DI):

<?php

namespace Drupal\mymodule;

use Drupal\Core\Session\AccountProxyInterface;

class MyClass {
  /**
   * @var AccountProxy
   */
  protected $currentUser;

  public function __construct(AccountProxyInterface $currentUser) {
    $this->currentUser = $currentUser;
  };

  public function doSomething() {
    $currentUserId = $this->currentUser->id();
    /* ... */
  }
}

Этот шаблон позволяет тестировать ваш код в полной изоляции с использованием фиктивного $currentUserобъекта (всего, что реализует AccountProxyInterfaceи может значительно сократить накладные расходы на обслуживание).

Тем не менее, DI не очень интуитивно понятен и требует времени, чтобы понять. То, как вы добавляете сервис в конструктор объектов, зависит от того, какой объект на самом деле находится в Drupal, например, плагины ведут себя не так, как зарегистрированные сервисы. Более подробная информация о DI в Drupal 8 содержится в документации do .

[edit] Предлагаемое редактирование этого ответа (которое было отклонено модераторами) введено public static function create()в код без дальнейшего объяснения. Однако было бы неверно добавлять этот метод класса без дальнейшего обсуждения.

Для справки, вот как должна выглядеть функция create ():

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('current_user')
    );
  }

Метод класса не используется никакими сервисами, которые вы регистрируете через модуль mymodule.services.yml: для них контейнер вызывает конструктор напрямую. Это всегда полезно для внедрения в не обслуживающие классы; например:

  • создание пользовательской формы: вы должны объявить, что реализуете, ContainerInjectionInterfaceчтобы контейнер знал, что нужно искать ::create().
  • создание плагина Drupal с использованием более широкой архитектуры плагинов: вы должны объявить, что реализуете ContainerFactoryPluginInterface, что требует другой сигнатуры метода ::create().

Это не место, чтобы расширять слишком много на внедрении зависимости, но дополнительная информация о ::create()методе доступна в этом блоге .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.