Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
456 views
in Technique[技术] by (71.8m points)

php - Making $_SESSION available in controllers

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

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

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...