PHPackages                             tomkirsch/psession - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. tomkirsch/psession

ActiveProject

tomkirsch/psession
==================

Persistent Session library for CI4

v2.2(3mo ago)031PHPPHP ^8.2

Since Jan 27Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/tomkirsch/ci4-psession)[ Packagist](https://packagist.org/packages/tomkirsch/psession)[ RSS](/packages/tomkirsch-psession/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (1)Versions (14)Used By (0)

Psession
========

[](#psession)

This module extend CI's Session and DatabaseHandler classes to provide persistent session functionality.

Installation
------------

[](#installation)

### Database

[](#database)

Create your DB tables:

```
CREATE TABLE IF NOT EXISTS `ci_sessions` (
  `id` varchar(40) NOT NULL,
  `user_id` int unsigned DEFAULT NULL,
  `ip_address` varchar(45) NOT NULL,
  `timestamp` int unsigned NOT NULL,
  `data` blob,
  primary key (id),
  KEY `user_timestamp` (`user_id`,`timestamp`)
) ENGINE=InnoDB

CREATE TABLE IF NOT EXISTS `ci_tokens` (
  `token_id` int unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int unsigned NOT NULL,
  `token_series` char(64) NOT NULL,
  `token_value` char(64) NOT NULL,
  `token_useragent` varchar(255) NOT NULL,
  `token_timestamp` int unsigned NOT NULL,
  primary key (token_id),
  KEY `user_series_useragent` (`user_id`,`token_series`,`token_useragent`(10))
) ENGINE=InnoDB

```

If you don't have some kind of users table, then you can also create this template and modify to suit your needs:

```
CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int unsigned NOT NULL AUTO_INCREMENT,
  `user_email` varchar(255) NOT NULL,
  `user_password` varchar(255) NOT NULL,
  `user_attempts` smallint UNSIGNED DEFAULT 0,
  `user_lastseen` datetime DEFAULT NULL,
  `user_created` datetime NOT NULL,
  `user_modified` datetime NOT NULL,
  primary key (user_id)
) ENGINE=InnoDB

```

Don't stress about the password field's case-insensitivity, as it's compared in PHP using password\_hash(), NOT in MYSQL.

### CodeIgniter

[](#codeigniter)

Open `App\Config\Session.php` and set the driver / table name. Note that $expiration and $regenerateDestroy will be overwritten, and thus have no effect.

```
public string $driver = \Tomkirsch\Psession\PersistentDatabaseHandler::class;
public string $savePath = 'YOUR_DB_TABLE';

```

Copy `PsessionConfig.php` into `App\Config` and modify the values to suit your needs (table names, field names, etc)

Ensure your encryption key is set in `app/Config/Encryption.php`:

```
	public $key = 'some string';

```

Ensure your database connection it set up in .env

Open up `app/config/Services.php` and overwrite the session function:

```
	public static function session(Session $config = null, bool $getShared = true)
    {
        $config ??= config('Session');
        if ($getShared) {
            return static::getSharedInstance('session', $config);
        }

        $logger = static::logger();
        $driverName = $config->driver;
        $driver     = new $driverName($config, static::request()->getIpAddress());
        $driver->setLogger($logger);

        $session = new Psession($driver, $config);
        $session->setLogger($logger);
        if (session_status() === PHP_SESSION_NONE) {
            $session->start();
        }
        return $session;
    }

```

You can opt to not start the session if you'd like more control over where that happens.

Now use it in your controllers:

```
class MyPage extends Controller{
	function index(){
		$session = service('session'); // attempts to read session from cookie, falling back on persistent cookies...
		if(empty($_SESSION['user_id'])){
			return $this->response->redirect('auth/login');
		}
		// user is logged in...
	}
}

class Auth extends Controller{
	protected function doLogin(string $email, string $password, bool $rememberMe){
		$session = service('session');
		// include session data, and find by email
		$user = $session->findSession()->where('user_email', $email)->get()->getFirstRow();
		if(!password_verify($password, $user->user_password)){
			// invalid login
		}else{
			// tell session that login was successful - this will set the persistent session cookies depending on $rememberMe
			$this->session->loginSuccess($user, $rememberMe);
			// save user data in $_SESSION
			$_SESSION['user_id'] = $user->user_id;
			// set 'remember me' cookie
			if($rememberMe){
				$this->response->setCookie([
					'name'=>'user_email',
					'value'=>$user->user_email,
					'expire'=> config('app')->persistentSessionExpiry,
					'secure' => TRUE,
					'httponly'=>TRUE,
					'samesite'=>'Lax',
				]);
			}else{
				$this->response->deleteCookie('user_email');
			}
		}
	}
	protected function doLogout(){
		$session = service('session');
		$session->destroy();
	}
}

```

###  Health Score

45

—

FairBetter than 93% of packages

Maintenance80

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~152 days

Recently: every ~210 days

Total

13

Last Release

103d ago

Major Versions

v1.0.5 → v2.0.02023-01-29

PHP version history (3 changes)v1.0.0PHP &gt;=7.2

v2.0.0PHP &gt;=7.4

v2.2PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/362359?v=4)[Thomas Kirsch](/maintainers/tkirsch)[@tkirsch](https://github.com/tkirsch)

---

Top Contributors

[![tomkirsch](https://avatars.githubusercontent.com/u/36715955?v=4)](https://github.com/tomkirsch "tomkirsch (11 commits)")

### Embed Badge

![Health badge](/badges/tomkirsch-psession/health.svg)

```
[![Health](https://phpackages.com/badges/tomkirsch-psession/health.svg)](https://phpackages.com/packages/tomkirsch-psession)
```

###  Alternatives

[codeigniter4/appstarter

CodeIgniter4 starter app

1891.8M](/packages/codeigniter4-appstarter)[abydahana/aksara

Aksara is a CodeIgniter based CRUD Toolkit you can use to build complex applications become shorter, secure and more reliable just in a few lines of code. Serving both CMS or Framework, produce both HEADLESS (RESTful API) or TRADITIONAL (Browser Based), just by writing single controller. Yet it's reusable, scalable and ready to use!

1101.2k](/packages/abydahana-aksara)[hermawan/codeigniter4-datatables

Serverside Datatables library for CodeIgniter4

10943.0k3](/packages/hermawan-codeigniter4-datatables)[agungsugiarto/boilerplate

CodeIgniter4 Boilerplate based on AdminLTE 3 with user management, roles, permissions, ...

1647.7k](/packages/agungsugiarto-boilerplate)[agungsugiarto/codeigniter4-cors

Send CORS Headers in a CodeIgniter 4 application.

6524.6k2](/packages/agungsugiarto-codeigniter4-cors)[jason-napolitano/codeigniter4-cart-module

A basic port of the codeigniter 3 cart module for CodeIgniter 4.

5814.8k](/packages/jason-napolitano-codeigniter4-cart-module)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
