olvlvl / composer-attribute-collector

A convenient and near zero-cost way to retrieve targets of PHP 8 attributes
Other
152 stars 3 forks source link

Support named arguments / arguments order #7

Closed xepozz closed 1 year ago

xepozz commented 1 year ago

Unordered named arguments cause exception. It's better to dive into example.

Attribute:

#[\Attribute(\Attribute::IS_REPEATABLE)]
class RouteAttribute
{
    public function __construct(
        public string $path,
        public ?string $name = null,
        public string|array $methods = [],
    ) {
    }
}

So parameters order is:

  1. Path
  2. Name
  3. Methods

Then let's take a look at the usage.

Class:

class SiteController
{
    #[RouteAttribute(path: '/test', methods: ['GET'], name: 'site/index')]
    public function test()
    {
        // ...
    }
}

The dump:

        \App\RouteAttribute::class => [
            [ ['/test', array (
  0 => 'GET',
), 'site/index'], \App\Controller\SiteController::class, 'test' ],
        ],

The order is:

  1. Path
  2. Methods
  3. Name

It's incorrect and won't work so php proves it: Caught unhandled error "App\RouteAttribute::__construct(): Argument #2 ($name) must be of type ?string, array given I'd suggest to generate the dump as parameter name => value, then the dump above will look like:

        \App\RouteAttribute::class => [
            [ ['path' => '/test', 'methods' => array (
  0 => 'GET',
), 'name' => 'site/index'], \App\Controller\SiteController::class, 'test' ],
        ],

If you do it array unpacking in \olvlvl\ComposerAttributeCollector\Collection::forClass will work correctly.

olvlvl commented 1 year ago

Great idea, Dmitry. I gotta say I never faced this issue because I follow the prompt of the IDE to sort arguments, like a good boy :) I'll look into it.

olvlvl commented 1 year ago

@xepozz Could you try these changes? https://github.com/olvlvl/composer-attribute-collector/pull/8

xepozz commented 1 year ago

I'll try them today or tomorrow