Sorry if this isn't the correct place to ask such a question.
Slim3 ships with Pimple, and the documentation I've read so far on the Slim3 docs seems to promote the Service Locator pattern. There's various articles that describe the Service Locator pattern as an anti-pattern. Such as this one: http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/
Was the choice to promote this pattern based on simplicity for the end user? I understand Slim3 is aimed at smaller applications rather than larger ones (although I have seen large applications with Slim3).
I use Slim in most of my applications and this was a question that crossed my mind.
The service locator is used in the documentation, but you don't have to use it. There's support for container resolution now, so you can leverage Pimple to handle your dependency injection.
Here's an example:
<?php
require_once "vendor/autoload.php";
$container = new \Slim\Container;
class Dep {
public function getSomething() {
return 'test text';
}
}
class TestController {
private $dep;
public function __construct(Dep $dep) {
$this->dep = $dep;
}
public function index() {
return $this->dep->getSomething();
}
}
$app = new \Slim\App($container);
//define DI in container
$container['dep'] = function() {
return new Dep;
};
$container['foo'] = function($c) {
return new TestController($c['dep']);
};
//resolve from container
$app->get('/','foo:index');
$app->run();
That being said, I don't think this is flushed out well in the documentation.
To just reiterate, if you have a string like 'foo:index', Slim will look for the 'foo' entry in the controller and then look for a function called 'index'. You can use a callable too and ditch the colon and second half, for example:
<?php
require_once "vendor/autoload.php";
$container = new \Slim\Container;
class Dep {
public function getSomething() {
return 'test text';
}
}
class TestController {
private $dep;
public function __construct(Dep $dep) {
$this->dep = $dep;
}
public function __invoke() {
return $this->dep->getSomething();
}
}
$app = new \Slim\App($container);
$container['dep'] = function() {
return new Dep;
};
$container['foo'] = function($c) {
return new TestController($c['dep']);
};
$app->get('/','foo');
If you do not have an entry in the container that matches the name, Slim will try to create the class itself and inject the container.
You have the ability to skip all that and define everything yourself, which I think is a better
As already noted, Slim fully supports DI.
The actual answer the question is that it's pragmatic - especially in anonymous functions. Not every developer is fully trained up on best practices and they just want to get their job done. Service location is a better decoupling technique than direct instantiation or static function calls, so I'd rather we promoted that for "RAD" scenarios than have statics...
Most helpful comment
The service locator is used in the documentation, but you don't have to use it. There's support for container resolution now, so you can leverage Pimple to handle your dependency injection.
Here's an example:
That being said, I don't think this is flushed out well in the documentation.