Skip to content

Instantly share code, notes, and snippets.

@boukeversteegh
Created October 7, 2015 16:36
Show Gist options
  • Save boukeversteegh/8ee54d988a52b0ba4288 to your computer and use it in GitHub Desktop.
Save boukeversteegh/8ee54d988a52b0ba4288 to your computer and use it in GitHub Desktop.
Migration to switch from file sessions to database sessions
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Session\FileSessionHandler;
use Illuminate\Session\DatabaseSessionHandler;
use Symfony\Component\Finder\Finder;
/**
* @author Bouke Versteegh
*/
class MoveFileSessionsToDatabase extends Migration
{
protected $fileSystem;
protected $fileSessionPath;
protected $fileSessionHandler;
protected $databaseSessionTable;
protected $databaseSessionHandler;
public function __construct()
{
$this->fileSystem = App::make('files');
$this->fileSessionPath = Config::get('session.files');
$this->fileSessionHandler = new FileSessionHandler($this->fileSystem, $this->fileSessionPath);
$this->databaseSessionTable = Config::get('session.table');
$this->databaseSessionHandler = new DatabaseSessionHandler(\DB::connection(), $this->databaseSessionTable);
}
public function up()
{
$sessionFiles = Finder::create()
->in($this->fileSessionPath)
->files()
->ignoreDotFiles(true);
foreach ($sessionFiles as $sessionFile) {
# Read file session
$sessionId = $sessionFile->getBasename();
$sessionData = $this->fileSessionHandler->read($sessionId);
# Create database session
$exists = DB::table($this->databaseSessionTable)->where('id', $sessionId)->exists();
if ($exists) {
DB::table($this->databaseSessionTable)->where('id', $sessionId)->update([
'payload' => base64_encode($sessionData),
'last_activity' => $sessionFile->getMTime(),
]);
} else {
DB::table($this->databaseSessionTable)->insert([
'id' => $sessionId,
'payload' => base64_encode($sessionData),
'last_activity' => $sessionFile->getMTime(),
]);
}
# Delete file session
$this->fileSessionHandler->destroy($sessionId);
}
}
public function down()
{
$sessionDatabaseRecords = DB::table($this->databaseSessionTable)->get();
foreach ($sessionDatabaseRecords as $sessionDatabaseRecord) {
# Read database session
$sessionId = $sessionDatabaseRecord->id;
$sessionData = base64_decode($sessionDatabaseRecord->payload);
# Create file session
$filePath = "{$this->fileSessionPath}/{$sessionId}";
$this->fileSessionHandler->write($sessionId, $sessionData);
touch($filePath, $sessionDatabaseRecord->last_activity);
# Delete database session
$this->databaseSessionHandler->destroy($sessionId);
}
}
}
@boukeversteegh
Copy link
Author

This migration cleanly moves all existing sessions from files into the database. Your users will not be logged out!

How to migrate Laravel file sessions to database

  • (optional) configure app/config/session.php, and specify the table you want to use for sessions
  • run artisan session:table
  • run artisan migrate:make move_file_sessions_to_database
  • paste the gist in the created migration
  • run artisan migrate
  • configure app/config/session.php to use database instead of file
<?php
return array(
   'driver' => 'database',
   /* ... */
);

This migration is not optimized for speed. It took about 30 minutes (EC2 t2.medium with a micro RDS 200GB, 300k sessions)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment