Access app in class in Slim Framework 3

前端 未结 5 1643
旧时难觅i
旧时难觅i 2021-02-05 23:33

Im having trouble understanding how to access the instance of Slim when a route is in a seperate class than index.php

When using Slim Framework 2 I always used the follo

5条回答
  •  醉梦人生
    2021-02-06 00:09

    Important

    I upvoted @mgansler and you should read that first if dealing with slim 3, and read this only if interested in differences to slim 2.


    Update

    So it seems those usages were just old code no one cleaned.

    However im leaving this post here as it should be helpful to anyone using Slim 2 (as slim 3 is very much still beta) and as a referance point to help see differences.


    Old Update (see above)

    Following update of OP, i looked at github source code and found that getInstance is still very much there, but with some slight differences perhaps...

    https://github.com/slimphp/Slim/search?utf8=%E2%9C%93&q=getInstance

    Test files (which maybe outdated, but unlikely) show something like this:

    public function testGetCallableAsStaticMethod()
    {
        $route = new \Slim\Route('/bar', '\Slim\Slim::getInstance');
    
        $callable = $route->getCallable();
        $this->assertEquals('\Slim\Slim::getInstance', $callable);
    }
    

    But at the same time we see calls like this in some files, which are obviously contextual and either return diff object ($env) or are in same static file (Slim.php)

    $env = \Slim\Environment::getInstance(true);
    
    static::getInstance();
    

    But this does show the static function still exists, so use my examples below and try to figure out why not working for you in current form.

    Also, this 'maybe' of interest, as only obvious example of slim3 in usage: https://github.com/akrabat/slim3-skeleton

    Though other projects prob exist, search with github filters if still having issues.



    Original Answer content

    Please include more detail on the route and the other class, but here are 3 ways, with execution examples detailed further down.

    This info does relate to Slim Framework 2, not the Slim 3 beta, but slim 3 beta shows similar example code and makes no mention of overhauling changes, and in fact links to the Slim 2 documentation: http://docs.slimframework.com/configuration/names-and-scopes/

    $this->app->getContainer()->get('rdb');
    
    // Recommended approach, can be used in any file loaded via route() or include()
    $app = \Slim\Slim::getInstance();
    
    Slim::getInstance();
    
    App::config('filename');
    

    Slim3 Beta has only one code example, which looks like this:

    $app = new \Slim\App();
    
    // which would by extension mean that this 'might' work too
    
    $app = \Slim\App::getInstance();
    
    // but be sure to try with slim2 naming just in case
    
    $app = \Slim\Slim::getInstance()
    

    Though obviously this doesnt fit outside of index.php, but is consistent with Slim2 doco showing GetInstance works.


    Which one fits you?

    I have multiple files that use these different approaches, though i cant say what fits best as too little context on how this external class fits in and what its composition is.


    For example, my controllers (which are endpoints of most my routes) use the same approach, through a base class or just direct:

    class ApiBaseController /// extends \BaseController
    {
    
        protected $app;
        protected $data;
    
        public function __construct()
        {
    
            $this->app = Slim\Slim::getInstance();
            $this->data = array();
    
        }
    
        //...
    
    }
    
    
    class VideoApiController extends \ApiBaseController
    {
    
        // ... 
    
    
        public function embed($uid)
        {
            // trace($this->app->response->headers());
            $vid = \R::findOne('videos'," uid = ? ",array($uid));
            if(!empty($vid))
            {
    
                // embed logic
    
            }else{
                // see my baseclass
                $this->app->render('api/404.html', array(), 404);
            }
        }
    
    
        // ...
    
    
    
    
        // Returns the video file, keeping actual location obscured
        function video($uid)
        {
            require_once(APP_PATH.'helpers/player_helper.php');
    
            $data = \R::findOne('videos'," uid = ? ",array($uid));
    
            /// trace($_SERVER); die();
    
            if($data)
            {
                stream_file($data['filename']);
            }else{
                $app = \Slim\Slim::getInstance();
                $app->render('404.html');
            }
    
            /// NOTE - only same domain for direct /v/:uid call
            header('Access-Control-Allow-Origin : '.$_SERVER['HTTP_HOST']);
            // header('X-Frame-Options: SAMEORIGIN');
    
            // Exit to be certain nothing else returned
            exit();
        }
    
    
        //...
    }
    


    My helper files show code like this:

    function get_permissions_options_list($context = null)
    {
        if(empty($context)) $context = 'user';
        return App::config('permissions')[$context];
    }
    


    My middleware:

    function checkAdminRoutePermissions($route)
    {
        $passed = runAdminRoutePermissionsCheck($route);
    
        if($passed)
            return true;
    
        // App::notFound();
        // App::halt(403, $route->getPattern());
    
        if(!Sentry::check())
            App::unauthorizedNoLogin();
        else
            App::unauthorized();
        return false;
    }
    


    Thats example of how i access in the various files, though the code you shared already shows that you have used the recommended approach already

    $app = \Slim\Slim::getInstance();
    

    Though again, need more info to say for sure how your external file fits in, but if its at the end of a route or in an 'include()', then it should work.

    You said your old approach didnt work though, but gave no info on what the actual result vs expected result was (error msg, ect), so if this doesnt work please update the OP.

提交回复
热议问题