
別アプリが稼働している環境へCodeIgniterを追加する必要が出てきました。その際にセッションを共有する必要がありました。
その際の作業内容をメモしておきます。
記事の目次
1. 前提条件
もともと稼働していたアプリは素のPHPで書かれたもので、ざっくり書くと下記のような感じ。
すでに稼働中のため、アプリ側に手を加えることができない状況です。
session_start(); $_SESSION['var'] = 'hoge';
2. とりあえず動かしてみる
まずは、現状の確認をするためにアプリ、CodeIgniter両方を動かしてみます。
2-1. 既存のアプリ側の挙動
アプリ側のセッションは下記のように生成されます。
$ cd /var/lib/php/session/ $ ls -l -rw------- 1 root root 0 2017-01-29 19:01 sess_e8ortt053tr6c1nrop7ad1qor1 -rw------- 1 root root 0 2017-02-02 09:10 sess_aagtr98n7mmcpdrq4k492p8ef6
プレフィックスのsess_
はphp内でハードコーディングされている定数です。ランダムな英数字は26文字です。セッションクッキーの名前はPHPSESSIDD
でした。
2-2. CodeIgniter側の挙動
一方、CodeIgniterは下記のように生成されました。
$ cd /var/lib/php/session/ $ ls -l -rw------- 1 root root 0 2017-01-29 19:01 ci_session5a5c728caa0cf776de78a14f9da64f149fb86a9f -rw------- 1 root root 0 2017-02-02 09:10 ci_session61ada784b1fd80dbc6442d4c24ec9c271b50ac39
プレフィックスはci_session
、ランダムな英数字は40文字、セッションクッキーの名前はci_session
でした。
セッションの保存場所は同じでしたが、下記の点が違いました。
- セッションクッキーの名前が異なる
- セッションのファイル名が異なる
- プレフィックスが異なる
- ランダムな英数字の文字数が異なる
それぞれを同じになるように調整をする必要があります。
3. セッションクッキーの名前 を合わせる
こちらは簡単です。application/config/config.php
を変更します。$config['sess_cookie_name']
を空文字にすることでini_get('session.name');
が利用されます。
$config['sess_cookie_name'] = '';
4. セッションのファイル名 を合わせる
こちらは、プレフィックス、文字数を変更します。
4-1. セッションファイルのプレフィックスを合わせる
Session_files_driver.php
を拡張するため、application/libraries/Session/drivers/MY_Session_files_driver.php
を作成します。ファイルの中は以下の通りです。sess_
はハードコーディングします。
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Session_files_driver extends CI_Session_files_driver { public function open($save_path, $name) { parent::open($save_path, $name); $this->_file_path = $this->_config['save_path'].DIRECTORY_SEPARATOR .'sess_' // ← ここがポイント .($this->_config['match_ip'] ? md5($_SERVER['REMOTE_ADDR']) : ''); return $this->_success; } }
4-2. セッションファイルの文字数を合わせる
ここが一番悩んだところでした。Session.php
の下記の箇所でアプリ側のセッションクッキーが削除されてしまい、セッションの共有ができませんでした。$this->_sid_regexp
の正規表現パターンにマッチしていませんでした。
// Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers if (isset($_COOKIE[$this->_config['cookie_name']]) && ( ! is_string($_COOKIE[$this->_config['cookie_name']]) OR ! preg_match('#\A'.$this->_sid_regexp.'\z#', $_COOKIE[$this->_config['cookie_name']]) ) ) { unset($_COOKIE[$this->_config['cookie_name']]); }
そこで、Session.php
を継承し、$this->_sid_regexp
を書き換えます。application/libraries/Session/MY_Session.php
として下記の内容でファイルを作成します。
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Session extends CI_Session { protected function _configure_sid_length() { parent::_configure_sid_length(); $this->_sid_regexp = preg_replace('#\A(.*)\{\d+\}\z#', '${1}+', $this->_sid_regexp); } }
以上で既存のアプリとCodeIgniter間でセッションの共有ができるようになりました。