title: PHP: ReflectionMethod::getAttributes throwing error 'Call to undefined method'
body: <p>I am very new to PHP (did some small projects a few years back, but nothing since) and trying to get familiar with it again by creating a RESTful API project. Coming from a C# background, I'm trying to setup the boiler plate stuff to be similar to that of .NET, where controllers handle the request and attributes help determine which function should handle the request.</p>
  <p>The problem I'm running into is retrieving the attributes from a method within the Controller class. I create an instance of <code>ReflectionClass</code>, call <code>getMethods()</code> then attempt to iterate the methods to retrieve the attributes by calling <code>$method-&gt;getAttributes(HttpGet::class)</code> but the <code>$method-&gt;getAttributes()</code> call is throwing the following error</p>
  <blockquote>
  <p>'PHP message: PHP Fatal error:  Uncaught Error: Call to undefined method ReflectionMethod::getAttributes() in /var/www/*********/api/base/ApiController.php:36\</p>
  </blockquote>
  <p>Here is the code
  -Running on Apache2 / Linux with PHP 7.4.28</p>
  <p><strong>The Controller</strong></p>
  <pre><code>    require './base/ApiController.php';
      require './base/attributes/RouteAttributes.php';
  
      class SessionController extends ApiController
      {
          #[HttpGet('')]
          public function OnGet()
          {
              parent::OK(&quot;GET Called - Returned 200 OK&quot;);
          }
  
          #[HttpPost('')]
          public function OnPost()
          {
              parent::Created(&quot;POST called - Returned 201 CREATED&quot;);
          }
      }
  
      $controller = new SessionController();
      ApiController::HandleRequest($controller);
  ?&gt;
  </code></pre>
  <p><strong>The ApiController base class</strong></p>
  <pre><code>    /* Base class for all API controllers, provides basic functionality like
       * returning common statuses, conversion of data to JSON and formatting 
       * appropriate headers
       */  
      require &quot;HttpStatusCode.php&quot;;
  
      class ApiController 
      {
          //Return Types
          public static function StatusCode(int $status, $data)
          {
              header('X-PHP-Response-Code: $status-&gt;value', true, $status);
              if(isset($data))
              {
                  header(&quot;Content-type: application/json&quot;);
                  echo json_encode($data);
              }
              exit;
          }
  
          public static function HandleRequest($controller)
          {
              $routePath = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : NULL;
              $requestMethod = strtoupper($_SERVER['REQUEST_METHOD']);
  
              $controllerInfo = new ReflectionClass($controller);
  
              $methodFound = false;
              switch($requestMethod)
              {
                  case 'GET':
                      foreach($controllerInfo-&gt;getMethods() as $method)
                      {
                          echo $method;
                           $getAttribute = $method-&gt;getAttributes(HttpGet::class);
                           if(count($getAttribute))
                           {
                               $method.invoke($controller, NULL);
                               $methodFound = true;
                           }
                      }
                      break;
                  case 'POST':
                      break;
  
              }
              if($methodFound == false)
                  ApiController::StatusCode(HttpStatusCode::NotFound, &quot;Method Not Found&quot;);
          }
  
  
          public function OK($data)
          {
              ApiController::StatusCode(HttpStatusCode::OK, $data);
          }
          
          public function Created($data, $createdAtRoute)
          {
              if(isset($createdAtRoute))
                  header('Location: $createdAtRoute');
  
              StatusCode(HttpStatusCode::Created, $data);
          }
          
          public function Accepted($data)
          {
              StatusCode(HttpStatusCode::Accepted, $data);
          }
          
          public function NoContent()
          {
              StatusCode(HttpStatusCode::NoContent, NULL);
          }
  
          public function BadRequest($data)
          {
              StatusCode(HttpStatusCode::BadRequest, $data);
          }
          
          public function Unathorized($data)
          {
              StatusCode(HttpStatusCode::Unathorized, $data);
          }
          
          public function Forbidden($data)
          {
              StatusCode(HttpStatusCode::Forbidden, $data);
          }
          
      }
  ?&gt;
  </code></pre>
  <p><strong>The Attribute definitions</strong></p>
  <pre><code>    #[Attribute]
      class HttpGet
      {
          public string $Route;
          public function __construct(string $route)
          {
              $this-&gt;Route = $route;
          }
      }
  
      #[Attribute]
      class HttpPost
      {
          public string $Route;
          public function __construct(string $route)
          {
              $this-&gt;Route = $route;
          }
      }
  
      #[Attribute]
      class HttpPut
      {
          public string $Route;
          public function __construct(string $route)
          {
              $this-&gt;Route = $route;
          }
      }
  
      #[Attribute]
      class HttpPatch
      {
          public string $Route;
          public function __construct(string $route)
          {
              $this-&gt;Route = $route;
          }
      }
  
      #[Attribute]
      class HttpDelete
      {
          public string $Route;
          public function __construct(string $route)
          {
              $this-&gt;Route = $route;
          }
      }
  ?&gt;
  </code></pre>
  <p>The project is very much still in the infancy stages and going to be a functional 'learner' project to get my feet wet. I just haven't been able to get past this error. Any help or insight would be greatly appreciated.</p>