Respect/Rest

Magic methods cause overload requires

Closed this issue · 1 comments

For example:

$router->any('/api/comments/', '\Api\Comments');
$router->any('/api/posts/
', '\Api\Posts');

When the url "/api/posts" is accessed, the files included are:
\Api\Comments and \Api\Posts

Because of this line: https://github.com/Respect/Rest/blob/develop/library/Respect/Rest/Router.php#L182
The function class_exists make the include.

A solution to overcome this problem is:
$router->classRoute('ANY', '/api/comments/', '\Api\Comments');
$router->classRoute('ANY', '/api/posts/
', '\Api\Posts');

@brunomp you are correct, the call to class_exists, to resolve a String as a Class name, will instruct PHP to load the class. You could instead use a literal identifier but then PHP will require you to import the Class with a use statement and this will load the classes. (b.t.w. the PHP manual suggests to always double escape quoted namespaces as the backslash otherwise has a different meaning when used in strings.) Even for your suggested solution, if it hasn't happened already it will be loaded when we wrap the class names in ReflectionObjects all the same.

This is not a problem, because php scripts should cause no side effects and aside from any static values that might be assigned this will have a marginal significance on state.

All handlers, with their defined routes and methods, are collected in Route adapters and subsequently wrapped in ReflectionObjects but it is only after the Route was matched to the specific request that the Request class calls runTarget and in the case of the ClassName Route classes, a new object is instantiated and the appropriate method is called for a response.

This is as lazy as it can possibly be and to ensure we don't waste all that effort we retain the reference to the instance for any subsequent calls, dependent on your configuration.

What you can try:

If you are concerned about the way we get your classes loaded you may want to use a Factory instead, define an interface to replace the "MyControllerClass" from the example and limit the loading to 1 interface and 1 factory. You can then decide how to load and instantiate your Routables from the same$method and $params variables that we use to identify the request.

If you look a little closer you will notice an added bonus as the params are passed by reference and inside you will find all the goodies to allow even more control over your requests. Yeeeah! \o/

This is issue therefor by design and a Factory will satisfy your requirement without complicating the API.

If you require a hand with Factories just ask, the pandas will gladly help =)

Have fun and Tx for your input!