phpphp-attributes

PHP attributes : is it possible to use static function for a attribute parameter value?


I have a project that use attributes :

    #[OperationQueryParam('id', IntegerOperation::class, requirements: new Numeric(min: 1, max: 2_147_483_647))]

Everything works fine but there are multiple attribute that have the same requirement argument new Numeric(min: 1, max: 2_147_483_647) so i wanted to create a static function in my numeric class :

    final public static function createPostiveInt(): self {
       return new self(min:1, max:2_147_483_647);
    }

then call the static function instead of the direct instanciation of the Numeric object to avoid repeating the constructor parameters.

    #[OperationQueryParam('id', IntegerOperation::class, requirements: Numeric::createPostiveInt())]

but i have this error : Compile Error: Constant expression contains invalid operations

Am i missing something ? Why does a direct instanciation works but not the static function ?

EDIT :

using define(POSITIVE_INT,Numeric::createPostiveInt()); works but it seems dirty.


Solution

  • From https://www.php.net/manual/en/functions.arguments.php:

    Default parameter values may be scalar values, arrays, the special type null, and as of PHP 8.1.0, objects using the new ClassName() syntax.

    In other words, you can't use a run-time construct like a function call as a default value for a parameter. You could extend the Numeric class here, to build-in your common defaults:

    class MyNumeric extends Numeric
    {
        public function __construct(int $min = 1, int $max = 2_147_483_647) {
            parent::__construct(min: $min, max: $max);
        }
    }
    

    Or even just remove the args completely:

    class MyNumeric extends Numeric
    {
        public function __construct() {
            parent::__construct(min: 1, max: 2_147_483_647);
        }
    }
    

    And then your definition becomes:

    #[OperationQueryParam(
        'id',
        IntegerOperation::class,
        requirements: new MyNumeric()
    )]