別アプリが稼働している環境へ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間でセッションの共有ができるようになりました。
[AD]