I've just started using the
database
last_activity
timestamp with timezone
Session
public function setLastActivityAttribute($ts){
$this->attributes['last_activity'] = date('c', $ts);
}
PDOException
SQLSTATE[22008]: Datetime field overflow: 7 ERROR: date/time field value out of range: "1506794381"
HINT: Perhaps you need a different "datestyle" setting. (SQL: delete from "sessions" where "last_activity" <= 1506794381)
timestamptz
I suggest creating a custom session driver by overwriting the gc
and expired
methods of the DatabaseSessionHandler.php
driver to work with timestamp with timezone
instead of integers.
The gc
currently passes time() - $lifetime
but you can change this to date('c', time() - $lifetime)
. And in expired
you can call strtotime
on $session->last_activity
to convert to the same unit as getTimestamp()
.
<?php
namespace App\Extensions;
use Illuminate\Session\DatabaseSessionHandler;
class MyPostgresHandler extends DatabaseSessionHandler
{
public function gc($lifetime) {
$sessions = $this->getQuery()->where('last_activity', '<=', date('c', time() - $lifetime))->get();
foreach ($sessions as $session) {
$this->destroy($session->id);
}
}
protected function expired($session)
{
return isset($session->last_activity) &&
strtotime($session->last_activity) < Carbon::now()->subMinutes($this->minutes)->getTimestamp();
}
}
Then you can register your new driver by extending ServiceProvider
<?php
namespace App\Providers;
use App\Extensions\MyPostgresHandler;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Session::extend('my-db-driver', function ($app) {
return new MyPostgresHandler;
});
}
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
Now you can use my-db-driver
in config/session.php
For more info see https://laravel.com/docs/5.5/session#implementing-the-driver