NotionCommotion Posted July 11, 2018 Share Posted July 11, 2018 Slim automatically passes the container to closure defined in the container. How can an additional parameter be passed such as my someOtherService() example? Thanks <?php require '../vendor/autoload.php'; use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; $app = new \Slim\App(/* as applicable */); $c = $app->getContainer(); $c['someService'] = function ($c) { return 'someService'; }; $c['someOtherService'] = function ($c, $id) { return 'someOtherService'; }; $app->get('/endpoint/{id:[0-9]+}', function (Request $request, Response $response, $args) use ($c) { //The following will all pass the container to someService and I believe are all identical ways to perform the same thing $someService1=$c['someService']; $someService2=$c->get('someService'); $someService3=$this->someService; //The following will not work since only the container is first passed to someOtherService() $someOtherService1=$c['someOtherService']($c, $args['id']); $someOtherService2=$c->get('someOtherService')($c, $args['id']); $someOtherService3=$this->someOtherService($c, $args['id']); }); Quote Link to comment Share on other sites More sharing options...
requinix Posted July 11, 2018 Share Posted July 11, 2018 Pimple (the container) only supports a single parameter, so either you make the value not be callable (so not a function or __invoke-able object) or you wrap the function in another function. If $id is required for the someOtherService factory, then what you need is a factory "factory" - the second one in quotes because really the container is about lazy loading, not about actually being a factory. $c['someOtherServiceFactory'] = function ($c) { return function ($id) use ($c) { return 'someOtherService'; }; }; The outer function gets evaluated the first time you use someOtherServiceFactory, and the value you get from the container is the inner function. $someOtherService1 = $c['someOtherServiceFactory']($args['id']); The container does have a raw() method that gives you the original value - your function($c,$id) - but I wouldn't use it because then you're completely ignoring the container's main lazy loading feature. You'd be using the container normally elsewhere, but not here where you can't use it normally and have to go through raw(). Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted July 12, 2018 Author Share Posted July 12, 2018 14 hours ago, requinix said: If $id is required for the someOtherService factory, then what you need is a factory "factory" - the second one in quotes because really the container is about lazy loading, not about actually being a factory. $c['someOtherServiceFactory'] = function ($c) { return function ($id) use ($c) { return 'someOtherService'; }; }; Thanks requinix, Your example of wrapping in a second function makes sense and so does your statement regarding lazy loading versus being a factory as well as your recommendation not to use raw(). Not sure, however, about having "the second one in quotes". Just to confirm, the script you posted afterwards pertains to wrapping in a second function and not about factory "factory", correct? Please elaborate on this part. Thanks Quote Link to comment Share on other sites More sharing options...
requinix Posted July 12, 2018 Share Posted July 12, 2018 It kinda contradicts what I said about lazy loading. The thought was "if a Pimple container acts as a factory" (which it kinda does) "then this would be a factory factory". As in you're using Pimple's own factory/lazy-loading mechanism to create a factory instead of some normal resource. $container["foo"] = function() { // this is a factory that only fires once return "foo"; // the product of the factory }; echo $container["foo"]; // invoke factory, get product, discard factory $container["bar"] = function() { // factory return function() { // product of the factory is itself a factory return "bar"; // product of the second factory }; }; echo $container["bar"] // invoke outer factory, get inner factory, discard outer factory (); // ...invoke inner factory, get product Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted July 13, 2018 Author Share Posted July 13, 2018 Gotcha. Thanks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.