Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to make the $_SESSION global available within the controllers of my framework written from scratch. It's not quite MVC, the presentation layer consists of two parent classes with multiple child classes.

Without going into great detail, my views are rendered in class Template

class Template{

    protected $_controller;
    protected $_action;

    function __construct($controller,$action) {
        $this->_controller = $controller;
        $this->_action = $action;
    }

    function render(){
        if (file_exists(APP_ROOT . DS . 'app' . DS . 'view' . DS . $this->_controller . DS . $this->_action . '.php')) {
            include (APP_ROOT . DS . 'app' . DS . 'view' . DS . $this->_controller . DS . $this->_action . '.php');
        }
    }

}

Then I'm calling Template::render() in a destructor within my parent controller after instantiating class Template within a constructor. All classes are being autoloaded.

class CoreController {

    protected $_controller;
    protected $_action;
    protected $_template;

    function __construct($controller, $action) {
        $this->_controller = ucfirst($controller);
        $this->_action = $action;

        $this->_template = new Template($controller,$action);
    }

    function __destruct() {
        $this->_template->render();
    }
} 

My question is how can I make $_SESSION available in CoreController and when exactly is it available during the shutdown sequence? I've tried calling it directly in CoreController as well as within Template::render() and always get undefined variable warnings, however defining $_SESSION within my views works. The reasoning behind this is I would like to set certain variables based off of whether or not the session id is set and I'd like to keep most presentation logic within my controllers. Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
431 views
Welcome To Ask or Share your Answers For Others

1 Answer

Session is a form of storage. Which means, that it should only be used deep within model layer.

Manipulating $_SESSION in presentation layer would be comparable with wring SQL in controllers and/or views. You would be eliminating the last vestiges of SoC ... though you have been already at it by implementing the Rails like "ViewController" monstrosity.

Instead of leaking your storage logic in the presentation layer, you should be using similar mappers like for the sql.

from some service in model layer

public function identify( $parameters )
{

    $user = $this->domainObjectFacctory->create('user');
    $mapper = $this->mapperFactory->create('session');

    if ( $mapper->fetch($user, 'uid') === false )
    {
        $mapper = $this->mapperFactory->create('user');
        $user->setUsername($parameters['login']);
        $user->setPassword($parameters['pass']);

        $mapper->fetch($user);
    }

    $this->currentUser = $user->isValid()
                       ? $user
                       : null;
}

The controller only interacts with services

public function postLogin( $request )
{
    $auth = $this->serviceFactory->create('recognition');
    $auth->identify([
        'login' => $request->getParameter('username'),
        'pass'  => $request->getParameter('password'),
        ]);
}

The service factory would be injected in the controller's (and the accompanying view's) constructor.

Note: the code above is only to illustrate the point and should not be copy-pasted or otherwise grafted on a production code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...