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

Multiple instances? #392

Open
aolko opened this issue May 24, 2018 · 1 comment
Open

Multiple instances? #392

aolko opened this issue May 24, 2018 · 1 comment

Comments

@aolko
Copy link

aolko commented May 24, 2018

Can i call multiple instances of klein in:
/index.php and let's say /modules/board/index.php
so they have routes of their own without being in one huge /index.php
(p.s. also interested how this will workout for .htaccess in both paths)

@eimajenthat
Copy link
Contributor

Well, I had a project where there was a main site, and a mobile site in the same code base, with different endpoints (so the main site was example.com and the mobile site was example.com/mobile/. For the mobile one, we had a separate routes file, which had its own routes. There was a separate RewriteRule pointing /mobile/{anything} at /mobile/index.php which took precedence over the general rule, which pointed things to /index.php.

It worked, but I'm not sure I would do it that way again, especially if you're real goal is modular routes, rather than a single offshoot. If you want to have lots of routes in separate files, this might be a little ghetto, but it would work:

<?php
require_once __DIR__ . '/vendor/autoload.php';

$klein = new \Klein\Klein();

// You will have to define this function, based on the structure of your application.
// It's supposed to return an array of strings which are the file paths for the route files.
$route_file_paths = get_route_file_paths();

foreach($route_file_paths as $path) {
    include __DIR__.$path;
}
$klein->dispatch();

That would require that each route file you include be well-behaved, and that it would declare its routes using $klein to refer to the \Klein\Klein object.

<?php
$klein->respond('GET', '/whatever', function(){return "stuff";});

Depending on the project, you might be able to get away with that, but I already admitted it's ghetto.

The next step up would be to implement an API in your module architecture for requesting routes. So you would have something like this:

<?php
require_once __DIR__ . '/vendor/autoload.php';

$klein = new \Klein\Klein();

// You will have to define this function, based on the structure of your application.
// It's supposed to return an array of objects which somehow represent your modules, and implement the method getRoutes().
$my_modules = get_my_modules();

foreach($my_modules as $mod) {
    // You would have to implement getRoutes in each module
    // It's supposed to return an array of "route signatures", a concept I just made up
    // Each route signature would be an associative array with three keys: method, pattern, action (you could probably have guessed that
    // They would contain the parameters to be passed to the respond method, as shown below
    foreach($mod->getRoutes() as $route) {
        $klein->respond($route['method'], $route['pattern'], $route['action']);
    }
}
$klein->dispatch();

That's just off the top of my head. If you started to implement this, you'd probably come up with a better way to implement it, but it would do roughly the same thing.

If you look at what the Klein::respond method is doing, it's just adding routes to a collection in inside itself, $this->routes: https://github.com/klein/klein.php/blob/master/src/Klein/Klein.php#L343

So you could make things a little more elegant like this:

<?php
require_once __DIR__ . '/vendor/autoload.php';

$klein = new \Klein\Klein();

// You will have to define this function, based on the structure of your application.
// It's supposed to return an array of objects which somehow represent your modules, and implement the method getRoutes().
$my_modules = get_my_modules();

foreach($my_modules as $mod) {
    // You would have to implement getRoutes in each module, which return an array of routes
    // See: https://github.com/klein/klein.php/blob/master/src/Klein/Route.php
    // See also: https://github.com/klein/klein.php/blob/master/src/Klein/RouteFactory.php
    foreach($mod->getRoutes() as $route) {
        $klein->routes()->add($route);
    }
}
$klein->dispatch();

It's basically the same thing as the one before, except the getRoutes method in each module would define an array of routes, instead of an array of arrays of the parameters required to define routes, which seems a little cleaner to me. There are probably still a lot of ways to improve upon the example above, but I think you get the idea.

So if you do what I did in real life, you'd have multiple Klein instances, and extra htaccess stuff. On the other hand, if you follow the variations on a theme I just proposed, you'd keep a single instance of Klein, and avoid extra htaccess/modrewrite config, which I think is better part of valor.

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