Search code examples
phpattributeshttp-status-code-500php-8.2

PHP Attribute Class not found error when trying to get new instance from ReflectionAttribute


I have this Attribute that I have created to control access level into my route methods.

namespace Lrc\Buscrawler\Attribute;

use Attribute;

#[Attribute(Attribute::TARGET_METHOD)]
class RouteAccess
{
    protected int $role;

    public const PUBLIC = 0;
    public const AUTHENTICATED = 1;
    public const ADMIN = 2;
    
    public function __construct($role)
    {
        $this->role = $role;
    }

    public function canAccess($sessionID)
    {
        error_log('Yes, you can.');
    }

}

This way I can put it into my controller methods to specify which role can access that route method, like this:

namespace Lrc\Buscrawler\Controller;

use Lrc\Buscrawler\Attribute\RouteAccess;

class UserController
{

    #[RouteAccess(RouteAccess::AUTHENTICATED)]
    public function profile()
    {
        echo '';
    }
}

And I pretend to use the canAccess method when resolving the routings, so I can check if that session can acess that route. The way I tried to do is like this:

namespace Lrc\Buscrawler\Service;

use ReflectionMethod;
use Lrc\Buscrawler\Attribute\RouteAccess;

class AccessService
{
    public static function canAccess($session, $controller, $method)
    {
        $con = new $controller();
        $refMethod = new ReflectionMethod($con, $method);
        $attributeRef = $refMethod->getAttributes(RouteAccess::class)[0];
        $attr = $attributeRef->newInstance();
        $attr->canAccess($session);
    }

}

I am getting an Attribute class not found (0) error at the $attributeRef->newInstance(), even though it is imported with use and has passed through the reference to that class in the previous line at getAttributes(RouteAccess::class)

The things I have tried already:

  • I have done some var_dump($attributeRef) to check the content of the variable, and it returned me a correct object(ReflectionAttribute)#23 (0) { }
  • I have tried the $attributeRef->getName() and it correctly returns me the expected value
  • I have tried the $attributeRef->getArguments() and it also gives me an error of Attribute class not found (0)
    • Changing the attributes from #[RouteAccess(RouteAccess::AUTHENTICATED)] to #[RouteAccess(2)], solves the problem calling $attributeRef->getArguments(), but not at $attributeRef->newInstance()

Solution

  • It was a typo where folder name was not equal to namespace defined for the files.