Skip to content

PHP 8.2 — Use standalone true, false, null types #48

@s2x

Description

@s2x

PHP 8.2 — Use standalone true, false, null types

Problem Description

PHP 8.2 introduces the ability to use true, false, and null as standalone types. Previously, they could only be used as part of a union type (e.g., string|false).

The code should be analyzed for places where these types could improve contract readability.

Location

Potential places to analyze:

  1. src/Reboot/Strategy/AlwaysRebootStrategy.php:9shouldReboot() method always returns true
  2. src/ConfigLoader.php:25isOptional() method always returns false
  3. Other methods returning constant boolean values

Analysis

AlwaysRebootStrategy::shouldReboot()

Current code:

final class AlwaysRebootStrategy implements RebootStrategyInterface
{
    public function shouldReboot(): bool
    {
        return true;
    }
}

Interface:

interface RebootStrategyInterface
{
    public function shouldReboot(): bool;
}

Analysis: The AlwaysRebootStrategy class implements the RebootStrategyInterface, which declares the return type bool. Changing to true in the implementation would violate the interface contract (covariance is allowed, but only in one direction — you can narrow, but not expand). In this case, changing booltrue is permissible in PHP 8.2+ (true is a subtype of bool), but would be a BC break for code that might rely on the method returning bool.

Conclusion: ❌ CANNOT change — class implements an interface.

ConfigLoader::isOptional()

Current code:

final class ConfigLoader implements CacheWarmerInterface
{
    public function isOptional(): bool
    {
        return false;
    }
}

Symfony interface (CacheWarmerInterface):

interface CacheWarmerInterface
{
    public function isOptional(): bool;
}

Analysis: Similarly to above, the class implements an external interface (Symfony), which requires returning bool.

Conclusion: ❌ CANNOT change — class implements an interface.

Other final classes without interfaces

Analyzed remaining final classes in the project:

  • Most final classes implement interfaces or inherit from external classes
  • Classes that do not implement interfaces and return constant values are usually events or DTOs

Proposed Solution

No code changes.

Standalone types true, false, null have limited applicability in this project due to:

  1. Large number of classes implementing interfaces (internal and external)
  2. Design convention based on interfaces
  3. Lack of final classes without interfaces returning constant boolean values

Where standalone types could be used (theoretically):

If the project had final classes without interfaces that return constant values:

// Hypothetical example — does not occur in the project
final class SomeService
{
    public function isEnabled(): true  // instead of bool
    {
        return true;
    }
    
    public function getDefaultValue(): null  // instead of ?string
    {
        return null;
    }
}

Priority

🔵 MINOR — limited applicability in this project.

Due to the architecture based on interfaces, standalone types do not bring significant benefits in this project. Changes would only be possible in final classes not implementing interfaces, of which there are few in this project.

Tests

Not applicable — no code changes.

Documentation

It is worth documenting in a comment or ADR (Architecture Decision Record) that standalone types have been analyzed and are not used due to:

  • Architecture based on interfaces
  • Need to maintain compatibility with interface contracts
  • Lack of final classes without interfaces returning constant values

Metadata

Metadata

Assignees

No one assigned

    Labels

    code-qualityCode quality improvementsminorMinor priority - code quality

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions