• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using session data within a model

#1
I've intialised a session in my BaseController as set out in the documentation, but I need to access/alter this session data from within my models. I'm at a loss how to go about doing this and would be grateful for any guidance.
Reply

#2
Alternatively, you can use the helper function that will use the default configuration options. This version is a little friendlier to read, but does not take any configuration options.


PHP Code:
$session session(); 

That is the session help method which should allow you to do what you need, it's a global.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply

#3
Since you have the $session object in your controller you could also pass it to the model when the model is constructed.

Passing objects to a class constructor as a way of supplying the object's dependencies is a very good habit to have. It's actually considered a best practice, especially if you're going to do unit testing of a class - and you really, really should unit test. Then passing dependencies to an object is pretty much a must.

So, one approach is to define a model like this.

PHP Code:
<?php namespace App\Models;

use 
CodeIgniter\Database\ConnectionInterface;
use 
CodeIgniter\Session\SessionInterface;

class 
UserModel
{
    protected $db;
    protected $session;

    public function __construct(ConnectionInterface &$dbSessionInterface &$session)
    {
        $this->db =& $db;
        $this->session =& $session
    }


Use the model like this in a controller

PHP Code:
// other controller code

$session Services::session();
$db = \Config\Database::connect();

$users = new UserModel($db$session);

// other code 

If your model is extending /CodeIgniter/Model then there are a few minor changes, but I bet you get the idea.
Reply

#4
(02-12-2020, 01:25 PM)InsiteFX Wrote: Alternatively, you can use the helper function that will use the default configuration options. This version is a little friendlier to read, but does not take any configuration options.


PHP Code:
$session session(); 

That is the session help method which should allow you to do what you need, it's a global.

Thank you, that appears like a good solution.
Reply

#5
(02-12-2020, 06:01 PM)dave friend Wrote: Since you have the $session object in your controller you could also pass it to the model when the model is constructed.

Passing objects to a class constructor as a way of supplying the object's dependencies is a very good habit to have. It's actually considered a best practice, especially if you're going to do unit testing of a class - and you really, really should unit test. Then passing dependencies to an object is pretty much a must.

So, one approach is to define a model like this.

PHP Code:
<?php namespace App\Models;

use 
CodeIgniter\Database\ConnectionInterface;
use 
CodeIgniter\Session\SessionInterface;

class 
UserModel
{
    protected $db;
    protected $session;

    public function __construct(ConnectionInterface &$dbSessionInterface &$session)
    {
        $this->db =& $db;
        $this->session =& $session
    }


Use the model like this in a controller

PHP Code:
// other controller code

$session Services::session();
$db = \Config\Database::connect();

$users = new UserModel($db$session);

// other code 

If your model is extending /CodeIgniter/Model then there are a few minor changes, but I bet you get the idea.

This was going to be my fallback method if I was unable to find another approach. I read with interest that you highlight this as a good habit to get into. You've given me some really food for thought. Thank you for taking the time to respond.
Reply

#6
(02-12-2020, 06:01 PM)dave friend Wrote: Since you have the $session object in your controller you could also pass it to the model when the model is constructed.

Passing objects to a class constructor as a way of supplying the object's dependencies is a very good habit to have. It's actually considered a best practice, especially if you're going to do unit testing of a class - and you really, really should unit test. Then passing dependencies to an object is pretty much a must.

So, one approach is to define a model like this.

PHP Code:
<?php namespace App\Models;

use 
CodeIgniter\Database\ConnectionInterface;
use 
CodeIgniter\Session\SessionInterface;

class 
UserModel
{
    protected $db;
    protected $session;

    public function __construct(ConnectionInterface &$dbSessionInterface &$session)
    {
        $this->db =& $db;
        $this->session =& $session
    }


Use the model like this in a controller

PHP Code:
// other controller code

$session Services::session();
$db = \Config\Database::connect();

$users = new UserModel($db$session);

// other code 

If your model is extending /CodeIgniter/Model then there are a few minor changes, but I bet you get the idea.

Hi Dave, final question (honestly!)

I've taken your route and am injecting the database and session object references into the model constructor, as you have shown. I am extending the the COdeIgniter model and consequently, my database methods are now failing quietly. Obviously I'm missing a crucial step.

At the moment I'm following the CI4 tutorial from the official documentation, so for example, there is a method 'getNews'  which returns all rows in a db table with $this->findAll().

This is failing. I have also tried $this->db->findAll() with similar results.

Any advice is much appreciated.
Reply

#7
(02-13-2020, 08:01 AM)Fido L Dido Wrote:
(02-12-2020, 06:01 PM)dave friend Wrote: Since you have the $session object in your controller you could also pass it to the model when the model is constructed.

Passing objects to a class constructor as a way of supplying the object's dependencies is a very good habit to have. It's actually considered a best practice, especially if you're going to do unit testing of a class - and you really, really should unit test. Then passing dependencies to an object is pretty much a must.

So, one approach is to define a model like this.

PHP Code:
<?php namespace App\Models;

use 
CodeIgniter\Database\ConnectionInterface;
use 
CodeIgniter\Session\SessionInterface;

class 
UserModel
{
    protected $db;
    protected $session;

    public function __construct(ConnectionInterface &$dbSessionInterface &$session)
    {
        $this->db =& $db;
        $this->session =& $session
    }


Use the model like this in a controller

PHP Code:
// other controller code

$session Services::session();
$db = \Config\Database::connect();

$users = new UserModel($db$session);

// other code 

If your model is extending /CodeIgniter/Model then there are a few minor changes, but I bet you get the idea.

Hi Dave, final question (honestly!)

I've taken your route and am injecting the database and session object references into the model constructor, as you have shown. I am extending the the COdeIgniter model and consequently, my database methods are now failing quietly. Obviously I'm missing a crucial step.

At the moment I'm following the CI4 tutorial from the official documentation, so for example, there is a method 'getNews'  which returns all rows in a db table with $this->findAll().

This is failing. I have also tried $this->db->findAll() with similar results.

Any advice is much appreciated.

Replying to my own post! I've finally fixed this. I realised that in my constructor method I also needed to place a call to the parent constructor method. All working now!
Reply

#8
Great. I'm happy to hear that. I suspected that was the problem.
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.