Use Constants in Traits in PHP 8.2

Use Constants in Traits in PHP 8.2

Traits provide a way to reuse code in classes without using inheritance. All properties and methods declared in trait are available within the class. Since PHP 8.2, we can use constants in traits. Trait constants can also be declared with visibility modifiers such as public, protected or private.

CommandTrait.php

<?php

trait CommandTrait
{
    public const SUCCESS = 0;
    public const FAILURE = 1;
}

Accessing trait constants

Trait constants cannot be accessed directly by using the trait name, either inside the trait, or from outside it.

CommandTrait.php

<?php

trait CommandTrait
{
    public const SUCCESS = 0;
    public const FAILURE = 1;

    public function test(): void
    {
        $status = self::SUCCESS;         // Valid
        $status = static::SUCCESS;       // Valid
        $status = CommandTrait::SUCCESS; // Error
    }
}
<?php

require_once 'CommandTrait.php';

CommandTrait::SUCCESS; // Error

The trait constants can be accessed via the class that uses the trait.

ReadFileCommand.php

<?php

class ReadFileCommand
{
    use CommandTrait;
}
<?php

require_once 'CommandTrait.php';
require_once 'ReadFileCommand.php';

ReadFileCommand::SUCCESS; // Valid

Overriding trait constants

Overriding trait constants is not allowed in the class that directly uses the trait. A class that uses the trait and declares a constant with the same name as in the trait, should use the same visibility modifier and value.

CommandTrait.php

<?php

trait CommandTrait
{
    public const SUCCESS = 0;
    public const FAILURE = 1;
    protected const DEBUG = false;
}

ReadFileCommand.php

<?php

class ReadFileCommand
{
    use CommandTrait;

    public const SUCCESS = 0;   // Valid
    public const FAILURE = -1;  // Error, different value
    public const DEBUG = false; // Error, different visibility modifier
}

A class that extends another class, which uses the trait, can override the constants declared in the trait.

ReadFileCommand.php

<?php

class ReadFileCommand
{
    use CommandTrait;
}

ReadCsvFileCommand.php

<?php

class ReadCsvFileCommand extends ReadFileCommand
{
    public const SUCCESS = 0;   // Valid
    public const FAILURE = -1;  // Valid
    public const DEBUG = false; // Valid
}

The trait constants can also be declared as final. It means that there is no way to override constant.

CommandTrait.php

<?php

trait CommandTrait
{
    final public const SUCCESS = 0;
}

ReadFileCommand.php

<?php

class ReadFileCommand
{
    use CommandTrait;
}

ReadCsvFileCommand.php

<?php

class ReadCsvFileCommand extends ReadFileCommand
{
    public const SUCCESS = 0; // Error
}

Leave a Comment

Cancel reply

Your email address will not be published.