Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when trying to use an object & method as a handler #25

Open
mav2287 opened this issue Mar 24, 2021 · 5 comments
Open

Error when trying to use an object & method as a handler #25

mav2287 opened this issue Mar 24, 2021 · 5 comments

Comments

@mav2287
Copy link

mav2287 commented Mar 24, 2021

I am trying to register a route with fast route using an Object and static method with the following code:

static public function registerRoute( RouteCollector &$r ): void {
  $r->addRoute(['GET', 'OPTIONS'], '/password', array( self::class, 'renderChallenge') );
}

instead of the handler being called I instead get the following error message:

Argument 1 passed to Middlewares\Utils\CallableHandler::__construct() must be callable, object given, called in /src/vendor/middlewares/utils/src/RequestHandlerContainer.php on line 51

In the course of trying to debug I decided to test if what I was passing was callable using the following:

// Regular function to check if something is callable
function isThisCallable( callable $callable  ) {
    call_user_func( $callable );
}

// Modified code from above
static public function registerRoutes( RouteCollector &$r ): void {
    $r->addRoute(['GET', 'OPTIONS'], '/password', function() {
       isThisCallable( array(static::class, 'renderChallenge') );
    } );
}

This test code ran as expected and called the static object's method. Is this a bug or is there another way I should be passing an object and method as the handler?

@oscarotero
Copy link
Member

The CallableHandler class is not receiving a callable element. Can I see the code including how are the middlewares implemented?

@mav2287
Copy link
Author

mav2287 commented Mar 24, 2021

After doing some additional testing the only ways I have found to make a static method call are by setting the handler to __CLASS__."::loginRedirect_renderChallenge" or invoking a new instance of the class, array( new self, "loginRedirect_renderChallenge" ). In terms of a static method call via an array I have yet to find anything that works other than invoking a new instance of the class. I also did a quick check and replaced self::class with the full name of the class array( 'namespace\Class', 'renderChallenge'), but still got the same error.

Below is how the Middlewares are implemented

// Emitter for response
$middlewares[] = new Middlewares\Emitter();

// Redirect to https
$middlewares[] = ( new Middlewares\Https() )->includeSubdomains();

// remove www
$middlewares[] = new Middlewares\Www(false);

// Removes the trailing slash
$middlewares[] = new Middlewares\TrailingSlash(false);

// Save the client ip in the '_ip' attribute
$middlewares[] = (new Middlewares\ClientIp())
    ->attribute('_client-ip');

// Log the request
/** @var Monolog\Logger $logger */
$middlewares[] = (new Middlewares\AccessLog( $GLOBALS['AccessLogger'] ) )
    ->ipAttribute('_client-ip');

// Negotiate the language
$middlewares[] = new Middlewares\ContentLanguage([ 'en', 'gl', 'es' ]);

// Handle Error Responses
$middlewares[] = new Middlewares\ErrorResponse();

// Negotiate the content-type
$middlewares[] = new Middlewares\ContentType();

// CORS Analyzer
/** @var Neomerx\Cors\Analyzer $CORS_analyzer */
$middlewares[] = new Middlewares\Cors( $GLOBALS['CORS_analyzer'] );

// Insert the X-Uuid header of the request and response. Useful for debugging purposes.
$middlewares[] = new Middlewares\Uuid();

// Calculate the response time
$middlewares[] = new Middlewares\ResponseTime();

// Add cache expiration headers
$middlewares[] = new Middlewares\CachePrevention();

// Sets header to disable robots
$middlewares[] = new Middlewares\Robots(false);

//Parse the json payload
$middlewares[] = new Middlewares\JsonPayload();

//Parse the urlencoded payload
$middlewares[] = new Middlewares\UrlEncodePayload();

// Set the route via fast-route
/** @var FastRoute\Dispatcher\GroupCountBased $router */
$middlewares[] = new Middlewares\FastRoute( $GLOBALS['router'] );

//Calls the callable handler from FastRoute
$middlewares[] = new Middlewares\RequestHandler();

$response = ( new Middlewares\Utils\Dispatcher( $middlewares ) )
    ->dispatch( Zend\Diactoros\ServerRequestFactory::fromGlobals() );

@oscarotero
Copy link
Member

oscarotero commented Mar 24, 2021

This is the code of RequestHandler middleware that decided how to handle your callable: https://github.com/middlewares/request-handler/blob/master/src/RequestHandler.php#L75

If it's a string (your case now), seems to work fine.

If it's an array (like your previous case Array(static::class, 'renderChallenge')) it enter here (https://github.com/middlewares/request-handler/blob/master/src/RequestHandler.php#L80) and try to get the class instance from the container. The class you're providing can be instantiated? or is static?

@mav2287
Copy link
Author

mav2287 commented Mar 24, 2021

The class can be instantiated the method it is calling is static.

@oscarotero
Copy link
Member

Ok, I'll take a look. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants