NotionCommotion Posted August 23, 2016 Share Posted August 23, 2016 I think I am on the right track. Slim has a Pimple container feature where a function could be added such as $container['logger'] = function($config) {/* ... */}; and within the callback, it could be used as $this->logger->addInfo('Hi!');. I wish to create something similar, but instead it will create a factory object. My difficulty I believe is passing the variables to the $this->factory(). What am I doing wrong? One other thing I don't understand is how $config is getting to the logger function. I would have thought that $config is global, and as such, I would need to do $container['logger'] = function() use $config {/* ... */};. I appear to be incorrect as the logger script works as shown below, and would appreciate some clarification what is going on. Thanks $config=[/* settings */]; $app = new \Slim\App(["settings" => $config]); $container = $app->getContainer(); $container['logger'] = function($config) { $logger = new \Monolog\Logger('my_logger'); $file_handler = new \Monolog\Handler\StreamHandler("../logs/app.log"); $logger->pushHandler($file_handler); return $logger; }; $container['db'] = function($config) { /* settings */}; $container['account'] = function($config) { /* settings */}; $container['factory'] = function ($request,$slim) { return new \MyApp\factory($request,$slim); }; $app->get('/configure', function (Request $request, Response $response) { $this->logger->addInfo('Hello world!'); return $response->withJson($this->factory($request,$this)->get()); }); class factory { private $request,$slim; public function __construct($request,$slim) { $this->request=$request; $this->slim=$slim; } public function createConfig() { return new \MyApp\Configure(['logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]); } public function createDocument() { return new \MyApp\Document(['id'=>$this->request->getAttribute('id'),'logger'=>$this->logger,'db'=>$this->db,'account'=>$this->account]); } } Quote Link to comment Share on other sites More sharing options...
kicken Posted August 23, 2016 Share Posted August 23, 2016 The function you set on the container is passed an instance of the container as it's first parameter: Pimple Documentation Notice that the anonymous function has access to the current container instance, allowing references to other services or parameters. If you want the global $config variable, you'd have to use it as you thought. In the case of your factory function service, you need to either pass a function that returns the factory function, or use the protect helper method. Because Pimple sees anonymous functions as service definitions, you need to wrap anonymous functions with the protect() method to store them as parameters: $container['random_func'] = $container->protect(function () { return rand(); }); Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted August 23, 2016 Author Share Posted August 23, 2016 Thanks Kicken, I seem to be missing something with the Pimple approach. Also, how would it look to pass a function that returns the factory function? $app->get('/configure', function (Request $request, Response $response) { var_dump($this->random_func); echo("\n"); var_dump($this->random_func()); exit; }); object(Closure)#26 (0) { } Fatal error: Call to undefined method Slim\Container::random_func() in /var/www/src/public/index.php on line 166 Quote Link to comment Share on other sites More sharing options...
kicken Posted August 23, 2016 Share Posted August 23, 2016 You can't call the factory function directly like that because PHP will not understand the code properly. $this->random_func is interpreted as 'Get me the random_func' property but $this->random_func() is interpreted as 'Call the random_func method'. Since the class doesn't have a random_func method you get the error. What you need to do is first get the random_func property, then call it as a function. In PHP 7 you can use parenthesis to force the proper interpretation: ($this->random_func)(); For older PHP versions you have to either use a variable or call_user_func. $random_func = $this->random_func; $random_func(); //or call_user_func($this->random_func); Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted August 23, 2016 Author Share Posted August 23, 2016 Thanks kicken, I guess I kind of knew that, but your excellent explanation made it sink in. Below is what I ended up doing. $container['factory'] = $container->protect(function ($request,$slim) { return new Factory($request,$slim); }); $app->get('/configure', function (Request $request, Response $response) { return $response->withJson(call_user_func($this->factory,$request,$this)->createConfig()->get()); }); If I decided not to use the Pimple protect method and instead pass a function, would it just be the following with the other part the same? $container['factory'] = $container->protect(function ($request,$slim) { return function($request,$slim) {new Factory($request,$slim);}; }); 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.