Problem/Motivation

State what you believe is wrong or missing from the current standards.

There are places in Drupal where we have string values referring to class names.

Often these values are initialized with regular string literals. This makes it hard for an IDE (I only tried with PhpStorm, no idea about others) to

  • list these string literals in "find usages" for a class.
  • provide auto-completion when writing this code.
  • warn you about non-existing or misspelled classes.
  • include these string literals in refactor/rename.

PHP provides a syntax where all this is supported: "::class".
I propose that this becomes the recommended way of referring to class names as strings.

Example

In Drupal\Core\Cache\ApcuBackendFactory::__construct():

Current code:

      $this->backendClass = 'Drupal\Core\Cache\ApcuBackend';

could be replaced with

      $this->backendClass = \Drupal\Core\Cache\ApcuBackend::class;

or better

[..]
use Drupal\Core\Cache\ApcuBackend;
[..]
      $this->backendClass = ApcuBackend::class;

Side note

The same problem exists with procedural callbacks, or string method names. Unfortunately there is no foo::function syntax in PHP. I personally always put a @see comment on top of string literals referring to functions or callbacks, to facilitate "find usages". But this should be dealt with in a separate issue.

Benefits

If we adopted this change, the Drupal Project would benefit by …

  • … making it easier to find all usages of a class (in IDEs or similar).
  • … providing auto-completion when writing this code.
  • … warn you about non-existing or misspelled classes.
  • … include these string literals in refactor/rename.

Three supporters required

  1. https://www.drupal.org/u/drunken-monkey (2025-02-23)
  2. https://www.drupal.org/u/borisson_ (2017-10-14)
  3. https://www.drupal.org/u/quietone (2026-04-19)

Proposed changes

1. PHP coding standards

Current text

None (new section)

Proposed text

Referencing classes

Whenever a class is referenced directly in code, the Classname::class syntax should be used, as in these examples:

class_alias(TranslatableMarkup::class, TranslationWrapper::class, TRUE);
uasort($info, [SortArray::class, 'sortByWeightElement']);
protected readonly string $pluginDefinitionAttributeName = Plugin::class;

2. PHP coding standards » Constructor calls

Current text

Note that if the class name is a variable, the variable will be evaluated first to get the class name, and then the constructor will be called. Use the same syntax:

$bar = 'MyClassName';
$foo = new $bar();
$foo = new $bar($arg1, $arg2);
Proposed text

Note that if the class name is a variable, the variable will be evaluated first to get the class name, and then the constructor will be called. Use the same syntax:

$bar = MyClassName::class;
$foo = new $bar();
$foo = new $bar($arg1, $arg2);

Remaining tasks

  1. Create this issue in the Coding Standards queue, using the defined template
  2. Add supporters
  3. Create a Change Record
  4. Review by the Coding Standards Committee
  5. Coding Standards Committee takes action as required
  6. Discussed by the Core Committer Committee, if it impacts Drupal Core
  7. Final review by Coding Standards Committee
  8. Documentation updates
    1. Edit all pages
    2. Publish change record
    3. Remove 'Needs documentation edits' tag
  9. If applicable, create follow-up issues for PHPCS rules/sniffs changes

For a full explanation of these steps see the Coding Standards project page

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

donquixote created an issue. See original summary.

donquixote’s picture

Issue summary: View changes
drunken monkey’s picture

+1
Didn't know about this feature until a few months ago, otherwise I would have used it in a lot more places in my modules. It's really much more practical with an IDE. (Another example: clicking the class name to go to the class.)
(Of course, we need a note to not use this in D7, since the feature was only added in PHP 5.5.)

pfrenssen’s picture

+1

This is one of the rare cases where we can actually have a tangible benefit (improved code navigability) through specifying the coding standards.

dawehner’s picture

Totally +1

klausi’s picture

Status: Active » Needs work
Issue tags: +Needs issue summary update

+1

The next step is to provide a concrete proposal in the issue summary what exactly we put into the coding standards document and where.

The ::class syntax is a PHP 5.5 feature, so we also need to mention that this only applies to Drupal 8. Drupal 7 code should not use this syntax.

bojanz’s picture

Oh, yes. +1

borisson_’s picture

Issue summary: View changes

+1.
I added a short example of how I think this should go in the rules. This is the first time I tried providing such a text, so it's probably not very clear and/or not long enough.

In any case, I'd love to see us doing this.

effulgentsia’s picture

Is this something that a Coder rule could be written for? Seems like a tricky one.

megachriz’s picture

@effulgentsia
Something like the follow regex?

$regex = '/= [\'\"]{1}(\\\\)?(\\\\)?[a-zA-Z\_0-9]+\\\\[a-zA-Z\_0-9\\\\]+[\'\"]{1}/';

This will match the following strings:

$var = '\Drupal\my_module\MyClass';
$var = 'Drupal\my_module\MyClass';
$var = "\\Drupal\\my_module\\MyClass";
$var = "Drupal\\my_module\\MyClass";

The regex should probably be adjusted a bit to ensure it doesn't match code in annotations and perhaps even 'normal' comments.

donquixote’s picture

The ::class syntax is a PHP 5.5 feature, so we also need to mention that this only applies to Drupal 8. Drupal 7 code should not use this syntax.

Or D7 contrib modules that explicitly require PHP 5.5+

quietone’s picture

Issue summary: View changes
drunken monkey’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs issue summary update

Updated the IS and added myself as a supporter. I didn’t find any appropriate section in the PHP coding standards so I propose adding a new one.

Btw, found this nugget in the class naming conventions which isn’t really up to date anymore (emphasis by me):

Classes should not use underscores in class names unless absolutely necessary to derive names inherited class names dynamically. That is quite rare, especially as Drupal does not mandate a class-file naming match.

drunken monkey’s picture

Issue summary: View changes
borisson_’s picture

Issue summary: View changes

Added my support as well, picked the date I originally posted a +1 on this issue.

borisson_’s picture

I'm not sure how we manage this, we've had multiple +1 statements on this issue, but we've moved to the supporter model in the IS, do we automatically count those as well?

quietone’s picture

Issue summary: View changes
quietone’s picture

Status: Needs review » Needs work

Needs work for a change record. Also needs review of the MR.

quietone’s picture

Title: Use C::class instead of 'C' for strings holding class names, to facilitate "find usages" in IDEs. » Use C::class instead of 'C' for strings holding class names
andypost’s picture

+1 as it helps navigation and better speed for php

borisson_’s picture

@webflo mentioned that https://getrector.com/rule-detail/string-class-name-to-class-constant-re... exists, that will help with the conversion.

Reviewed the merge request, that looks great. Next thing is writing the change record.

borisson_’s picture

Status: Needs work » Needs review

Added a draft change record.