1

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.

7
  • Just call session_start during bootstrap phase of the process and you should be able to get at it over the life of the request Commented May 20, 2013 at 12:55
  • Your suggestion works great, thanks again! your server tip the other day was a lifesaver. I wonder if I should do what teresko suggested and use it within the model layer, that would probably involve sending it through the dispatcher which seems like a better approach if I were being picky. Commented May 20, 2013 at 13:26
  • IMHO it belongs in the controller. If you put it in the modal you are creating a dependency between the modal and use pattern that requires session, so utilizing the modal say in a from script wouldn't be possible. Commented May 20, 2013 at 13:32
  • @Orangepill, so, just because you do not want to abstract superglobal, you decide to destroy SoC? Commented May 20, 2013 at 13:38
  • 2
    $_SESSION is a superglobal, so it is available everywhere. And for the shutdown phase, superglobals are killed within, sessions sometime in there closed. There is a nice talk by Johannes Schlüter, see PHP Shutdown Sequence ca. 25:50 Commented May 20, 2013 at 13:55

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the suggestion, what's the best way to handle this? I was thinking defining $_SESSION within the dispatcher than calling it within the parent model construct.
The initialization of session object (the abstraction for $_SESSION usperglobal) should be done in the factory, that creates the data mappers for the services. The same factory would also ensure that the session object is only created once, without need for singletons or other bad practices.
Ok so from this perspective if I understand, initialize $_SESSION in memory then interact with it through the presentation layer, forgive the shorthand. Seems like the most logical approach.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.