Since PHP 8.0, constructor property promotion allows declaring class properties directly in the constructor signature:
public function __construct(
protected EntityTypeManagerInterface $entityTypeManager,
) {}
This is syntactic sugar for:
protected EntityTypeManagerInterface $entityTypeManager;
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
) {
$this->entityTypeManager = $entityTypeManager;
}
Promoted parameters are class fields, not regular function parameters. However, rule S117 treats them as regular parameters and flags them when they don’t match the parameter naming convention.
This produces false positives when the project uses a different naming convention for properties and parameters. For example, in Drupal:
-
Class properties: camelCase (
$entityTypeManager) -
Local variables and function parameters: snake_case (
$entity_type_manager)
With S117 configured for snake_case (^[a-z][a-z0-9_]*$), every promoted property using the correct camelCase convention is flagged.
Noncompliant Code (false positive)
With S117 configured for snake_case parameters:
class NodeAccessHandler {
public function __construct(
protected EntityTypeManagerInterface $entityTypeManager, // S117 flags this — FALSE POSITIVE
protected AccountProxyInterface $currentUser, // S117 flags this — FALSE POSITIVE
) {}
public function checkAccess(NodeInterface $node, string $operation): AccessResult {
$access_records = $this->entityTypeManager->getStorage('node_access')->loadMultiple();
// ...
}
}
$entityTypeManager and $currentUser are class properties, not parameters. Their camelCase naming is correct per the property convention. S117 should not flag them.
Compliant Code
The code above is compliant — no changes needed. S117 should simply skip promoted properties.
Mixed constructor (promoted and non-promoted parameters)
class MyService {
public function __construct(
// Promoted → class property → S117 should NOT check this
protected EntityTypeManagerInterface $entityTypeManager,
// NOT promoted → regular parameter → S117 SHOULD check this
string $module_name,
) {}
}
S117 should only validate $module_name. $entityTypeManager should be excluded from S117 because it is a promoted property (rule S116 “Field names should comply with a naming convention” is the appropriate rule for it).
Exceptions
S117 should exclude constructor parameters that have any of:
-
A visibility modifier:
public,protected, orprivate -
The
readonlymodifier -
Any combination (e.g.,
public readonly)
These keywords mark a parameter as promoted (i.e., a class property), and the parameter naming convention should not apply to them.
External References
-
PHP RFC: Constructor Property Promotion (PHP 8.0)
-
PHP Manual: Constructor promotion
-
Drupal coding standards: Naming conventions — snake_case for variables/parameters, camelCase for class properties
-
Drupal core uses promoted properties with camelCase extensively since Drupal 10
-
Symfony and Laravel also widely use constructor promotion with camelCase
Type
Bug — S117 raises false positives on a standard PHP 8.0+ language feature widely adopted since 2020.