Created
December 8, 2014 22:09
-
-
Save epixa/d0e11ffc7243848578ee to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// A traditional route in slim: | |
$app->get('/foo/:id', someMiddleware, function($id) use ($app) { | |
$app->response->headers->set('x-custom-header', 'foo'); | |
$app->render('foo.php', ['id' => $id]); | |
}); | |
// This is a very convenient pattern for small apps that can not only | |
// declare but also define all routes in a single file, but it has some | |
// drawbacks for larger apps: | |
// 1. Every routing function must close over $app, since $app is the | |
// only way to interact with request/response in any capacity | |
// 2. Routes cannot be autoloaded since they are just functions | |
// 3. All middleware and routing functions used anywhere must be | |
// defined on every request | |
// 4. Cannot easily reuse common behaviors throughout routes since they | |
// are just anonymous functions | |
// 5. Route functions are encouraged to be heavily coupled to slim | |
// | |
// The nice thing about slim is that the conventions it encourages are | |
// really convenient for many types of apps, but you also aren't required | |
// to follow those conventions. Many MVC frameworks represent controllers | |
// as literal classes that have individual methods (usually called actions) | |
// that can be tied to route definitions. In addition to organizing common | |
// routing behaviors, this sort of implementation allows routes to be defined | |
// via configuration and then autoloaded as the request dictates. | |
// | |
// So with a small amount of effort, you could define the prior example as: | |
$router->route('GET /', 'FooCtrl@foo')->with('someMiddleware'); | |
class FooCtrl | |
{ | |
use Renderable; | |
public function foo($id, $request, $response) { | |
$response->headers->set('x-custom-header', 'foo'); | |
$this->render('foo', ['id' => $id]); | |
} | |
} | |
// Because slim is small and flexible, it is possible to use controllers and | |
// actions in a slim app without a bunch of hackery. You can even make your | |
// controllers and actions completely decoupled from slim itself, which | |
// promotes testability and portability. This is what I accomplished, more or | |
// less, with the SDO library in https://github.com/epixa/scheduled-do | |
// | |
// It's not perfect; it was mostly just a rough prototype, but it is tested | |
// and it wouldn't take a ton of work to make it completely reusable on any | |
// existing or new slim app. These are the things it does right now: | |
// 1. Routes are configured in a separate file without having to actually | |
// load/define all of the corresponding middleware and routing functions. | |
// 2. Routes are powered by actions (methods) on controllers (classes) | |
// 3. Controllers do not need to extend a base class, so no required coupling | |
// to slim itself | |
// 4. Middleware can be configured on a route-by-route basis and only be | |
// loaded when they match the current request | |
// 5. Dependency injection via service locator, which can be any service | |
// container you choose that implements that container-interop interface | |
// (the scheduled-do app itself uses php-di) | |
// | |
// So basically, the library provides some mechanisms that can help organize | |
// larger projects when you still ultimately want slim running under the hood. | |
// | |
// If I were to finish it to be released as a stand-alone open source project, | |
// I'd appreciate any and all feedback. I'd like to know what specific problems | |
// people have faced when using slim for larger projects. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment