🔄

PHP 5.2からLaravel 11への大規模リニューアル #1 プロジェクト概要と課題分析

に公開

はじめに

こんにちは。あべじーです。ブログを書く会社でブログを書かない寄りの仕事を行っています。
所属してる部ではZennの運営も行っていますが、私は別チームで動いております。

今回から数回にわたって、アニメ・ラジオ番組情報サイト「Aniradi Network」を、最新のLaravel環境へ完全リニューアルしたプロジェクトについて、その過程と学びを共有したいと思います。

※Aniradi Networkと今の所属会社は一切の関係性はございません。

本プロジェクトの特徴的な点は、開発の各段階でClaude Code(Anthropic社のAI開発ツール)を活用し、技術選定から実装まで効率的に進められたことです。
20年以上稼働していたPHP 5.2ベースのシステムを、どのようにして現代的なWebアプリケーションに生まれ変わらせたのか、その開発手法と技術的な解決策を詳しくご紹介します。
読み物としてお楽しみいただければと思います。

プロジェクトの背景

Aniradi Networkとは

Aniradi Networkは、アニメ・ラジオ番組の情報を集約し、ファンコミュニティを形成するWebサービスです。
1998年にAniradi Terminalというサービスで開始し、今のAniradi Networkは2000年代初頭からエー・エヌ・ピーにより運営されています。
Aniradi Networkは以下のような機能を提供しています:

  • 番組情報の検索・閲覧
  • 放送スケジュールの確認
  • ゲスト出演情報の投稿・共有
  • イベントレポート・ニュース機能
  • ユーザーレビューとお気に入り機能
  • ユーザーコミュニケーション機能(チャット・掲示板)

なぜリニューアルが必要だったのか

長年の運用により、以下のような技術的負債が蓄積していました:

レガシーシステムの構成:
- PHP 5.2(2011年1月でサポート終了)
- MySQL 4.0.30(2008年12月でサポート終了)
- 文字コード: EUC-JP (eucjpms)
- ストレージエンジン: MyISAM(トランザクション非対応)
- フレームワーク: なし(独自実装)
- バージョン管理: なし

技術的な課題と制約

1. セキュリティリスク

サポート終了から10年以上経過したPHP 5.2は、多数の脆弱性を抱えていました:

  • SQLインジェクションの危険性
  • XSS攻撃への脆弱性
  • セッション管理の不備
  • パスワードのMD5ハッシュ保存(レインボーテーブル攻撃に脆弱)

2. メンテナンス性の問題

// 旧システムのコード例(実際のテーブル構造)
<?php
// グローバル変数の多用
$db = mysql_connect($host, $user, $pass);
mysql_select_db("aniradi", $db);

// SQLの直接記述(インジェクション脆弱性あり)
$sql = "SELECT * FROM program WHERE Program_ID = '" . $_GET['id'] . "'";
$result = mysql_query($sql);

// 文字コードの手動変換
$title = mb_convert_encoding($row['Program_name'], 'UTF-8', 'EUC-JP');

// MD5によるパスワード管理(脆弱)
$pass = md5($_POST['password']);

このような実装により:

  • コードの可読性が低い
  • SQLの直接記述(プリペアドステートメント未使用)
  • テストが困難
  • 機能追加・修正に時間がかかる
  • 新規開発者の学習コストが高い

3. パフォーマンスの限界

  • インデックスの不足(PRIMARY KEYのみ)
  • MyISAMエンジンによる全文検索の制限
  • N+1問題の多発
  • キャッシュ機構の欠如
  • トランザクションサポートなし(MyISAM)
  • 非効率なクエリの蓄積

4. 文字コード問題

EUC-JPを使用していたため:

  • 絵文字が使えない
  • 一部の漢字が文字化け
  • 他システムとの連携が困難

5. リニューアルを阻んでいた要因

実は、これらの問題は10年以上前から認識されていました。しかし、以下の理由でリニューアルが実現できませんでした:

技術的な障壁

  • システムが日常的に使用されており、手を付けられないほど陳腐化が進行
  • 2013年以降、新規データの登録ができない状態に陥っていた(日付フィールドの制約)
  • フレームワークを利用していなかったため、段階的なリニューアルが困難
  • レガシーコードの複雑な依存関係により、部分的な改修も困難

時間的な制約

  • リニューアル期間が長期化することで、その間にさらなる技術的負債が蓄積する懸念
  • やりたい機能改善をコードに落とし込む時間的余裕がない
  • まとまった開発時間の確保が困難

リソースの限界

  • 設計・実装・テスト・移行のすべてを担うことが現実的でない
  • 新技術の学習コストが高く、実装に移るまでに時間がかかりすぎる

6. Claude Codeがもたらした転機

2025年5月にClaude Codeの正式版がリリースされました。
さらに6月5日にはProプラン(月額$20)での利用が可能になり、個人開発者でも手頃な価格でAI支援開発が利用できるようになりました。
この状況変化により、従来は不可能だった短期間でのリニューアルが現実的になったのです:

  • 開発速度の劇的な向上:複雑なマイグレーションコードを対話的に生成
  • 技術的ハードルの低下:Laravel 11の最新機能を学習しながら実装
  • 品質の担保:テストコードの同時生成、セキュリティ考慮点の自動チェック

この機会を逃すと、さらなる技術的負債の蓄積により、将来的なリニューアルがより困難になることが明白でした。
そこで、2025年6月末にリニューアルプロジェクトを敢行することを決断しました。

データ規模と複雑性

移行対象のデータ規模:

データ種別 レコード数 特記事項
ユーザー (anp_user) 859 MD5パスワードの再ハッシュ化必要
番組情報 (program) 1,666 カラム名が大文字小文字混在
番組スケジュール (programtable) 約500 番組データ
放送局 (station) 約200 周波数・送信所情報含む
ニュース記事 (news) 116 HTMLタグとEUC-JP混在
ゲスト情報 (guest) 11,191 Program_IDとの紐付け
インターネット配信 (inet) 146 WMP/RealPlayer時代の配信情報

プロジェクトの目標と開発手法

このような状況を踏まえ、以下の目標を設定しました。
また、これらの実現にあたってはClaude Codeを積極的に活用する新しい開発アプローチを採用しました:

技術的目標

  1. 最新技術スタックへの移行

    • PHP 8.3 + Laravel 11
    • MySQL 8.0
    • UTF-8mb4対応
  2. セキュリティの強化

    • SQLインジェクション対策
    • CSRF対策
    • 適切な認証・認可
  3. 保守性の向上

    • MVCアーキテクチャ
    • テスタブルなコード
    • コーディング規約の導入

ビジネス目標

  1. ユーザー体験の向上

    • レスポンシブデザイン
    • 高速な検索機能
    • リアルタイム通知
  2. 運用効率の改善

    • 自動デプロイ
    • エラー監視
    • バックアップ自動化

リニューアルのアプローチ

フェーズ分割による段階的移行

一度に全てを移行するのではなく、以下のフェーズに分けて実施しました。:

データ移行戦略

  1. 並行稼働期間の設定

    • 旧システムを稼働させたまま新システムを構築
    • データの二重管理期間を最小限に
  2. 段階的なデータ移行

    • マスタデータから移行
    • トランザクションデータは最後に
    • Claude Codeによる移行スクリプトの自動生成
  3. 文字コード変換の自動化

    • EUC-JP → UTF-8mb4の変換スクリプト作成
    • 文字化けの検出と修正ロジックの実装

まとめ

今回は、Aniradi Networkのリニューアルプロジェクトの概要と、直面した課題について説明しました。
20年以上稼働してきたレガシーシステムの刷新において、Claude Codeを開発パートナーとして活用することで、従来では考えられない速度と効率で開発を進めることができました。

次回は、新システムのアーキテクチャ設計と技術選定について、どのようにLaravelを選定し、最適な設計方針を導き出したのかを詳しくご紹介します。

次回予告

次回以降の記事では、以下の内容をお届けします:

  • Laravelを選んだ理由
  • データベース設計の刷新
  • 認証・認可システムの設計
  • API設計とフロントエンド連携

お楽しみに!

Discussion