Provide FieldableEntityInterface get() functionality that returns NULL instead of throwing exception

Created on 24 December 2024, 27 days ago

Problem/Motivation

When retrieving field values from content entities, it is best practice and safest to check whether the field exists first. Code can look like this:

if ($entity->hasField('field_my_field')) {
  $value = $entity->get('field_my_field')->value;
}

This is because FieldableEntityInterface::get() throws an InvalidArgumentException if the field does not exist.

Since PHP 8 provides the null-safe operator, it would be nice to be able to do something like
$value = $entity->get('field_my_field')?->value instead, with get(), or some equivalent, returning NULL instead of throwing an exception for an invalid field name.

Steps to reproduce

Proposed resolution

Two main approaches come to mind:

  1. Add an optional boolean second parameter to get(), which controls whether the method returns NULL or throws an exception. By default, the exception would continue to be thrown. Example:
    /**
       * Gets a field item list.
       *
       * @param string $field_name
       *   The name of the field to get; e.g., 'title' or 'name'.
       *
       * @param bool $throw_exception
       *   Whether to throw an exception if field name is invalid or return NULL.
       *
       * @return \Drupal\Core\Field\FieldItemListInterface|null
       *   The field item list, containing the field items.
       *
       * @throws \InvalidArgumentException
       *   If an invalid field name is given.
       */
      public function get($field_name, bool $throw_exception = TRUE);
    
  2. Add a new method that returns NULL instead of throwing an exception. This could possibly be a wrapper for get(). For example, doing something like the following in ContentEntityBase (method name could use some work):
    /**
       * Gets a field item list safely.
       *
       * @param string $field_name
       *   The name of the field to get; e.g., 'title' or 'name'.
       *
       * @param bool $throw_exception
       *   Whether to throw an exception if field name is invalid or return NULL.
       *
       * @return \Drupal\Core\Field\FieldItemListInterface|null
       *   The field item list, containing the field items.
       */
      public function safeGet(string $field_name): ?FieldItemListInterface {
        try {
          return $this->get($field_name);
        }
        catch (\InvalidArgumentException) {
          return NULL;
        }
      }
    

Changing the interface with either would be a breaking change, though. (Or introducing a new method could be done with a new interface.)

Remaining tasks

User interface changes

Introduced terminology

API changes

Either a change to the signature of FieldableEntityInterface::get() or a new method that returns NULL instead of throwing an exception.

Data model changes

Release notes snippet

📌 Task
Status

Active

Version

11.0 🔥

Component

entity system

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024