Drupal - How do I get the user ID for the currently logged-in user?

$user = \Drupal::currentUser();

See the Drupal class. There are a lot of helper methods; most of them are shortcuts for services, so you don't have to call \Drupal::service() directly.

Note that the current user is not the user entity, it is just user proxy. You can get some basic information from it but fields or other entity-specific logic is not present. To access the user entity you have to load it manually:

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

Unfortunately there is no direct method like \Drupal::currentUser()->getEntity() :(


Example of how to load current user and retrieve field data from user object.

<?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;
?>

Accessing methods on the \Drupal global class (like ::currentUser()) is OK in procedural code (e.g. in your mymodule.module file) but in your own OO code you should try to access the @current_user service, via a standard pattern called dependency injection (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();
    /* ... */
  }
}

This pattern permits your code to be tested in complete isolation, with a dummy $currentUser object (anything which implements AccountProxyInterface, and can hugely reduce maintenance overheads.

However, DI isn't very intuitive and takes a while to understand. How you get the service into your object constructor depends on what the object actually is in Drupal e.g. plugins behave differently from registered services. There's more information on DI in Drupal 8 in the d.o docs.

[edit] A suggested edit to this answer (which was rejected by moderators) introduced public static function create() into the code, with no further explanation. However, it'd be misleading to add this class method without any further discussion.

For reference, this is what the create() function would look like:

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

The class method is not used by any services you register via a module's mymodule.services.yml: for these, the container calls the constructor directly. It's only ever useful for injecting into non-service classes; for example:

  • creating a custom form: you must declare you implement ContainerInjectionInterface so that the container knows to look for ::create().
  • creating a Drupal Plugin, using the wider Plugin architecture: you must declare you implement ContainerFactoryPluginInterface, which demands a different method signature for ::create().

This isn't the place to expand too much on dependency injection, but further information about the ::create() method is available on this blogpost.

Tags:

Users

8