NotionCommotion Posted May 8, 2018 Share Posted May 8, 2018 I typically implement slim as follows: <?php use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; require '../vendor/autoload.php'; function getConfig() { //... return $config; } $c = new \Slim\Container(['settings' => array_merge([ 'displayErrorDetails'=>true, // set to false in production 'addContentLengthHeader'=>false, // Allow the web server to send the content-length header 'determineRouteBeforeAppMiddleware'=>true ],getConfig())] ); $c['view'] = function ($c) { $view = new \Slim\Views\Twig(__DIR__.'/../src/templates', [ //'cache' => 'path/to/cache' // See auto_reload option 'debug' => true, 'strict_variables'=> true ]); $view->addExtension(new \Slim\Views\TwigExtension( $c['router'], $c['request']->getUri() )); $view->addExtension(new \Twig_Extension_Debug()); //$view->getEnvironment()->addGlobal('path', $uri->getPath()); //If desired on all pages return $view; }; $c['someClass'] = function($c) { return new \SomeClass($c['settings']['server']); }; $c['someOtherClass'] = function($c) { return new \SomeOtherClass(); }; $app = new \Slim\App($c); $app->post('/someEndpoint', function (Request $request, Response $response) { $rsp=$this->get('someClass')->someMethod([]); //Returns array with content and HTTP status code. return $response->withJson($rsp[0],$rsp[1]); }); $app->get('/someEndpoint', function (Request $request, Response $response) {/*...*/}); $app->get('/someOtherEndpoint', function (Request $request, Response $response) {/*...*/}); $app->add(function(Request $request, Response $response, $next) { //Add middleware }); $app->run(); I know need an endpoint which based on a ContentType parameter will either render a page which contains text obtained from another API or will download a file based on this other API, and am using the following: $app->get('/guids/{guid}/logs/{id:[0-9]+}', function (Request $request, Response $response, $args) { switch($request->getQueryParam('ContentType')) { case 'text': return $this->view->render($response, 'log.html', [ 'server'=>$this->get('base')->getServer(), 'menu_main'=>$this->get('base')->getMenu('/guids'), 'backupDate'=>$this->get('base')->restApi('get', _VER_.'/backup')[0], 'content'=>$this->get('base')->restApi('get', _VER_."/guids/$args[guid]/logs/$args[id]",['ContentType'=>'text'])[0], ]); break; case 'file': $config=$this->get('settings')['server']; $query=$request->getUri()->getQuery(); $query=$query?"?$query":null; $url=$config['ip']._VER_."/guids/$args[guid]/logs/$args[id]$query"; $context = stream_context_create(['http'=>['header'=>'X-User-Key: '.$config['key']]]); $fh = fopen($url, 'rb', false, $context); //r or rb? $stream = new \Slim\Http\Stream($fh); $headers = $stream->getMetadata()['wrapper_data']; $forwardHeader=[ 'Content-Description'=>'File Transfer', 'Content-Type'=>'application/octet-stream', 'Content-Transfer-Encoding'=>'binary', 'Content-Disposition'=>'attachment; filename="replaced_name"', 'Expires'=>0, 'Cache-Control'=>'must-revalidate, post-check=0, pre-check=0', 'Pragma'=>'public', 'Content-Length'=>false, //Possible to get stream length? ]; foreach ($headers as $header) { $header=explode(':',$header); if($header && count($header)==2 && isset($forwardHeader[$header[0]])){ //Should I really be modifying the $response? $response=$response->withHeader($header[0],trim($header[1])); unset($forwardHeader[$header[0]]); } } //Is this necessary? foreach ($forwardHeader as $key=>$value) { if($value!==false){ $response=$response->withHeader($key,$value); } } return $response->withBody($stream); break; default: return $response->withJson('Invalid requested content type',422); } }); To improve readability, I desire my endpoint scripts to be very concise as shown in my previous script, and perhaps I need need to use this script for other endpoints, so I wish to more it to a separate method. I guess I could (and maybe should) make a separate class with a single method, but I was trying to move it to another function in the container instead and am having issues. I was thinking of something like the following: $c['ContentType'] = function ($c) { return function($request, $response, $args) { switch($request->getQueryParam('ContentType')) { case 'text': return $this->view->render($response, 'log.html', [ //.... ]); break; case 'file': //.... return $response->withBody($stream); break; default: return $response->withJson('Invalid requested content type',422); } }; }; $app->get('/guids/{guid}/logs/{id:[0-9]+}', function (Request $request, Response $response, $args) { return $this->ContentType($request, $response, $args); }); However, no matter what I tried, I either find that ContentType is not a valid method or that I am trying to pass one parameter instead of the expected three to it. How can this be implemented? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/307257-directly-accessing-a-method-in-the-slim-container/ 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.