エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

PHPのセッション管理入門

こんにちは。エンジニアリンググループGMの高島です。

マネジメントチームブログリレー8日目の記事を担当します。7日目は河合さんの『今年もエムスリーアドベントカレンダー開幕します!』でした。

そう、これは エムスリー Advent Calendar 2025 1日目の記事でもあります。

京都南禅寺の水路閣。
違う時代の建造物が混在する趣は、レガシーコードを読むときの感覚に似ています。

背景

私がいま兼任しているエムスリーテクノロジーズで、グループ会社が持つレガシーアプリケーションのリファクタリングを支援することになりました。 10年以上前から稼働しているPHPのアプリケーションで、フレームワークも導入されておらず、画面表示とデータベースアクセスが渾然一体となったモノリシックなソースコードが、数十万行あります。

もちろん開発チームもこれを課題だと捉えていましたが、好調なビジネスを支える屋台骨のアプリケーションであり、大規模障害につながりかねない大きな改善にはなかなか手を出せずにいました。 しかしビジネスをさらに成長させる上で、今のままでは必要な開発速度を達成できないため、アプリケーションを構造化・モジュール化するリファクタリングに着手することになりました。

リファクタリングの方針と課題

モジュール化を進める上で、設計方針の共有といった観点からフレームワークは不可欠だと考え、開発チームがストレス少なく移行できそうなLaravelを導入することに決めました。

導入にあたって絶対に外せない要件が段階的な移行です。 今回のアプリケーションの規模を考えると、ビッグバンリリースは困難かつ極めて危険であり、機能単位あるいは画面単位で細かく移行する必要があると考えました。

そうすると移行期間中は新旧のアプリケーションが混在することになり、それらの間でのデータ共有が問題となります。 データベースに永続化されるアプリケーションデータもそうですが、セッション情報のような一時データも考慮が必要です。 調べてみると、Laravelと素のPHPではセッション管理の方式が色々と異なり、そのままではデータを共有できないことが分かりました。

素のPHP Laravel
セッションIDのキー名 PHPSESSID laravel_session
セッションIDの長さ 32文字 40文字
データ形式 独自 PHP標準のシリアライズ

対策

セッションIDのキー名

セッションIDをCookieに設定するときのキー名として、素のPHPがPHPSESSIDを使うのに対しLaravelはlaravel_sessionを使います。 これは環境変数を以下のように設定するだけで統合できます。

SESSION_COOKIE=PHPSESSID

セッションIDの長さ

PHPSESSIDの長さはデフォルトで32文字ですが、セキュリティが強化されたLaravelの標準は40文字となっており、短いIDを許容しません。 なのでいったん制約を緩めるSessionStoreクラスを用意します。

<?php

class NativeSessionStore extends Store
{
    public function isValidId($id)
    {
        // 32文字のセッションIDを許容する
        return is_string($id) && ctype_alnum($id) && strlen($id) === 32;
    }
}

はやく移行を完了させて、Laravel標準のセッションIDを使うようにしたいですね。

データ形式

<?php

$_SESSION['user_name'] = 'Taro';
$_SESSION['user_id'] = 123;
$_SESSION[’_token'] = 'csrf-token-123';

のようなセッション情報を保存した場合、素のPHPでは以下のように記録されます。

user_name|s:4:"Taro";user_id|i:123;_token|s:14:"csrf-token-123";

これに対してLaravelは、PHPの標準関数であるserialize()を使ってシリアライズするので、以下のように記録されることを期待します。

a:3:{s:9:"user_name";s:4:"Taro";s:7:"user_id";i:123;s:6:"_token";s:14:"csrf-token-123";}

このギャップを埋めるため、素のPHPが記録したセッション情報をLaravelが期待する形式に変換する、SessionHandlerクラスを用意しました。

<?php

class NativeSessionHandler implements SessionHandlerInterface
{
    public function read(string $id): string|false
    {
        :
        // session_decode()を使ってデコード
        session_decode($data);
        :
    }

    public function write(string $id, string $data): bool
    {
        :
        // 連想配列をPHPネイティブセッション形式にエンコード
        foreach ($data as $key => $value) {
            $result .= $key.'|'.serialize($value);
        }
        :
    }
}

まとめ

以上のように対応することで、新旧のアプリケーションで問題なくセッションを共有できるようになりました。 今はどんどん移行を進めているところです。

私はこれまでPHPを書いたことがありませんでしたが、それでもスムーズに進められているのは、藤原さんも言っているようにAIエージェントの力が大きいと感じています。使い慣れた言語を1人で書いていたときよりも、間違いなく高い成果が出ています。

また私自身がコードを書く時間を確保できるようになったのは、マネジメントチームが拡大して1人あたりのマネジメント業務の負担が減ったおかげです*1。 継続的にリーダー/マネージャーを輩出するエムスリーの仕組みを、ぜひグループ会社でも実現したいですね。

We are hiring!!

エムスリーやエムスリーテクノロジーズでは、ジュニアもシニアもマネージャーもインディビジュアル・コントリビューターも絶賛募集中です。 カジュアル面談や面接の申し込みをお待ちしています!

jobs.m3.com

www.m3t.co.jp

*1:私がマネジメントチームに入ったときは4人でした。今は倍以上に増えています!