PHP5からPHP8への移行実践ガイド - 効率的なツールと手順
はじめに
どのプログラミング言語に関してもバージョンアップグレードは避けて通れない重要なタスクです。本記事では、実際のアプリケーション(400+ファイル)のPHP5からPHP8への移行経験をもとに、効率的な移行手順とツールの活用方法を解説します。
目次
PHPとは
PHPは、主にWebアプリケーション開発で使用されるサーバーサイドスクリプト言語です。多くのWebサイトやWebアプリケーションで採用されており、HTMLに埋め込んだりデータベースと連携したりすることで動的なWebページを生成することができます。
PHP5からPHP8の主な変更点
項目 | PHP5 | PHP8 | 影響 |
---|---|---|---|
MySQL関数 | mysql_connect() |
削除済み → mysqli_connect() |
🔴 手動修正必須 |
配列アクセス | $arr{0} |
非推奨 → $arr[0] |
🟡 自動修正可能 |
制御構文 | if(): endif; |
非推奨 → if() {} |
🟡 自動修正可能 |
文字列関数 | split() |
削除済み → explode() /preg_split() |
🟡 自動修正可能 |
配列関数 | each() |
削除済み → foreach |
🟡 自動修正可能 |
PHP4コンストラクタ | function ClassName() |
非推奨 → __construct() |
🟡 自動修正可能 |
正規表現 | ereg() |
削除済み → preg_match() |
🔴 手動修正必須 |
マジッククォート | magic_quotes_* |
削除済み | 🔴 手動修正必須 |
型宣言 | 限定的 | 厳格な型システム | 🟢 新機能 |
パフォーマンス | 基準 | 2-3倍高速 | 🟢 改善 |
PHP移行について
プログラミング言語のバージョンアップとは?
プログラミング言語は継続的に進化し、セキュリティ修正、パフォーマンス向上、新機能追加のためにバージョンアップされます。PHP5は2014年にサポートが終了しており、セキュリティリスクと互換性の問題が存在します。
移行のメリットとチャレンジ
メリット:
- セキュリティの向上
- パフォーマンスの大幅改善(PHP8はPHP5の約2-3倍高速)
- 新機能の利用可能(Union型、Named Arguments等)
- 継続的なサポート
チャレンジ:
- 非推奨関数の大量修正
- ライブラリの互換性問題
- テストとデバッグの工数
移行前について
1. 開発環境の構築
VS Codeに以下のプラグインをインストール:
プラグイン | 用途 | 移行での活用方法 |
---|---|---|
PHP Intelephant | PHPの基本サポート | 構文エラーをリアルタイムで検出、赤い波線で問題箇所を表示 |
PHP CodeSniffer | コード品質チェック | 互換性問題を事前に発見、コーディング標準の維持 |
PHP Refactor | リファクタリング支援 | 関数名変更、構造の改善を効率的に実行 |
VS Codeの活用ポイント:
- Find & Replace機能: 大量のファイルで一括置換が可能
- エラー表示: 問題のあるコードを赤い波線で視覚的に確認
- 検索機能:
Ctrl+Shift+F
で残存する問題コードを素早く発見
2. PHP CodeSniffer(PHPCS)のセットアップ
PHPCSとは: PHPコードの品質をチェックし、コーディング標準違反や互換性問題を検出するツールです。今回の移行では、PHP8との互換性問題を自動で発見し、一部は自動修正してくれます。
# PHP CodeSnifferのインストール
composer require --dev squizlabs/php_codesniffer
# PHP互換性チェッカーのインストール
composer require --dev phpcompatibility/php-compatibility
# 設定
./vendor/bin/phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility
.gitignoreに追加する理由:
# Composer
vendor/
composer.phar
Composerは数千のファイルをvendor/
ディレクトリにダウンロードします。これらはライブラリファイルなので、Gitリポジトリには含まれないようにgitignoreに追加します。
3. 互換性チェックの実行
# 基本的なチェック
./vendor/bin/phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0 --extensions=php --ignore=*/vendor/* -p .
# メモリが不足する場合(大規模プロジェクト用)
./vendor/bin/phpcs -d memory_limit=1G --standard=PHPCompatibility --runtime-set testVersion 8.0 --extensions=php --ignore="*/vendor/*" -p .
メモリ増設が必要な理由: 400+ファイルの大規模プロジェクトでは、全ファイルを同時に解析するため大量のメモリを消費します。デフォルトの128MBでは不足するケースが多いです。
自動化ツールによる移行
1. PHP CodeSniffer Fixer(PHPCBF)による自動修正
PHPCBFとは: PHP CodeSniffer Fixerの略で、PHPCSが検出した問題を自動で修正するツールです。構文的な問題や基本的なコーディングスタイルの修正が可能です。
# 自動修正の実行
./vendor/bin/phpcbf --standard=PHPCompatibility --runtime-set testVersion 8.0 --extensions=php --ignore="*/vendor/*" -p .
# メモリ不足の場合
./vendor/bin/phpcbf -d memory_limit=1G --standard=PHPCompatibility --runtime-set testVersion 8.0 --extensions=php --ignore="*/vendor/*" -p .
自動修正される項目(主要なもの):
- 配列・文字列アクセスの波括弧記法 (
$string{0}
→$string[0]
) - 制御構文の代替記法 (
if(): endif;
→if() {}
) - 一部の非推奨構文
- コーディングスタイルの修正
注意: PHPCSでは構文的な修正のみ可能で、ロジックを伴う複雑な変更(MySQL関数の置換等)は対応できません。
2. Rectorによる包括的な自動修正
インストール
composer require rector/rector --dev
vendor/bin/rector # 初期設定(yesで回答)
設定ファイル (rector.php)
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/foldername',
__DIR__ . '/foldername',
__DIR__ . '/foldername',
__DIR__ . '/foldername',
// プロジェクトの主要ディレクトリを指定
])
->withSkip([
__DIR__ . '/foldername',
__DIR__ . '/foldername',
__DIR__ . '/foldername',
])
->withSets([
LevelSetList::UP_TO_PHP_83, // PHP5.3からPHP8.3まで段階的アップグレード
SetList::CODE_QUALITY, // コード品質改善
SetList::DEAD_CODE, // デッドコード除去
SetList::EARLY_RETURN, // early returnパターン適用
SetList::NAMING, // 命名規則改善
])
->withImportNames();
実行
# プレビュー(変更内容の確認)
vendor/bin/rector process --dry-run --memory-limit=2G
# 大規模プロジェクトの場合、ディレクトリ別に処理
vendor/bin/rector process foldername/ --dry-run --memory-limit=2G
vendor/bin/rector process foldername/ --dry-run --memory-limit=2G
vendor/bin/rector process foldername/ --dry-run --memory-limit=2G
# 実際の適用
vendor/bin/rector process --memory-limit=2G
メモリ増設が必要な理由: Rectorは非常に高度な解析を行うため、大量のファイルを処理する際は2GB程度のメモリが必要になることがあります。
Rectorが自動修正する項目:
split()
→explode()
またはpreg_split()
each()
→foreach
- PHP4形式のコンストラクタ →
__construct()
- 配列構文の現代化 (
array()
→[]
) - 制御構文の代替記法 (
if(): endif;
→if() {}
) - コード品質の改善
- デッドコードの除去
注意: マジッククォート関連のコードは自動修正されないため、手動での対応が必要です。
手動修正が必要な項目
1. MySQL関数の移行(最重要)
PHP7.0で削除されたMySQL関数を手動でMySQLiに変更する必要があります。これは自動化ツールでは対応できない最も重要な作業です。
自動修正できない理由: MySQL関数とMySQLi関数では、パラメータの順序や必須パラメータが異なるため、単純な文字列置換では対応できません。
// 旧 → 新
mysql_connect() → mysqli_connect()
mysql_select_db() → mysqli_select_db()
mysql_query() → mysqli_query()
mysql_fetch_assoc() → mysqli_fetch_assoc()
mysql_fetch_array() → mysqli_fetch_array()
mysql_num_rows() → mysqli_num_rows()
mysql_affected_rows() → mysqli_affected_rows()
mysql_real_escape_string() → mysqli_real_escape_string()
mysql_error() → mysqli_error()
mysql_close() → mysqli_close()
データベース接続の例:
// 旧コード
$con = mysql_connect(DB_HOST, DB_USER, DB_PASS);
mysql_select_db(DB_NAME, $con);
// 新コード
$con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if (!$con) {
die('DBに接続できません: ' . mysqli_connect_error());
}
VS Code活用のコツ:
Ctrl+Shift+H
でFind & Replaceを開き、mysql_connect
等を一括置換- 置換後、エラー表示(赤い波線)で修正が必要な箇所を確認
2. 配列キーの安全なアクセス
PHP8では未定義の配列キーアクセスで警告が発生するため、適切なチェックが必要:
# VS Codeで一括検索して修正箇所を特定
grep -rn "\$_GET\[" . --include="*.php" | head -10
grep -rn "\$_POST\[" . --include="*.php" | head -10
grep -rn "\$_SESSION\[" . --include="*.php" | head -10
// 旧コード(警告が発生)
$value = $_GET['param'];
// 新コード
$value = $_GET['param'] ?? '';
// または
$value = isset($_GET['param']) ? $_GET['param'] : '';
3. 非推奨ライブラリの更新/置換
PHPExcel → PhpSpreadsheet
# 古いPHPExcelを削除
grep -rn "PHPExcel" . --include="*.php" | head -5
# 新しいライブラリをインストール
composer require phpoffice/phpspreadsheet
// 旧
require_once 'PHPExcel.php';
$objPHPExcel = new PHPExcel();
// 新
require_once 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
$spreadsheet = new Spreadsheet();
Pearライブラリ(Pager等)の手動設置
# 必要なライブラリを手動ダウンロード
mkdir -p Pager
curl -o Pager.php https://raw.githubusercontent.com/pear/Pager/master/Pager.php
mv Pager.php Pager/
mkdir -p Pager/Pager
curl -o Pager/Pager/Common.php https://raw.githubusercontent.com/pear/Pager/master/Pager/Common.php
curl -o Pager/Pager/Jumping.php https://raw.githubusercontent.com/pear/Pager/master/Pager/Jumping.php
curl -o Pager/Pager/Sliding.php https://raw.githubusercontent.com/pear/Pager/master/Pager/Sliding.php
4. その他の非推奨関数と構文
// split() → explode() または preg_split()
// 旧
$parts = split("/", $string);
// 新
$parts = explode("/", $string);
// または正規表現が必要な場合
$parts = preg_split("/\//", $string);
// ereg() → preg_match()
// 旧
if (ereg("pattern", $string)) {
// 新
if (preg_match("/pattern/", $string)) {
検証とテスト
重要: 移行作業を開始する前に、現在のPHP5環境でアプリケーションが正常に動作することを確認してください。移行完了後も同様にテストを行い、すべての機能が仕様通りに動作することを検証する必要があります。
1. 構文エラーのチェック
# 個別ファイルのチェック
php -l ./filename.php
# 一括チェック
find . -name "*.php" -exec php -l {} \;
2. 残存問題の検索
コマンドラインでの検索:
# MySQL関数の残存チェック
grep -r "mysql_" --include="*.php" .
# その他の非推奨関数
grep -r "split(" --include="*.php" .
grep -r "each(" --include="*.php" .
grep -r "ereg" --include="*.php" .
grep -r "magic_quotes" --include="*.php" .
VS Codeでの検索:
Ctrl+Shift+F
でワークスペース全体を検索- 正規表現を使用した高度な検索が可能
- 検索結果からファイルを直接開いて修正
3. Docker環境での動作確認
注意: このセクションはDockerを使用してローカル開発環境を構築している場合の手順です。
Dockerfile/docker-compose.ymlの更新
# Dockerfile
FROM php:8.0-apache # PHP5から PHP8に変更
# docker-compose.yml
version: '3'
services:
web:
image: php:8.0-apache # バージョン更新
動作テストでの追加修正
Docker環境でアプリケーションを実際に動かすと、静的解析では発見できなかった問題が見つかることがあります:
- ランタイムエラーの発生
- ライブラリの動作不良
- データベース接続の問題
これらの問題は実際にアプリケーションを動かしながら一つずつ修正していく必要があります。コードが動作しない箇所をログやエラーメッセージから特定し、適切に修正を行ってください。
まとめ
PHP5からPHP8への移行は、適切なツールを使用することで大幅に効率化できます:
成功のポイント:
- PHPCS + PHPCBF: 基本的な互換性問題の検出と自動修正
- Rector: 包括的なコード現代化
- VS Code: Find&Replace、エラー検出、検索機能の活用
- 段階的アプローチ: 自動修正 → 手動修正 → テスト
- 十分な検証: Docker環境でのテスト、構文チェック
残る手動作業:
- MySQL関数の移行(最重要)
- 配列キーアクセスの安全化
- マジッククォート関連コードの削除
- 非推奨ライブラリの置換
- ereg関数のpreg_match置換
この手順により、数週間かかる可能性があった移行作業を大幅に短縮できました。重要なのは段階的なアプローチと十分なテストです。一度に全てを変更せず、コミットを細かく分けて進捗を管理することで、問題が発生した際の切り戻しも容易になります。
参考リンク
- PHP CodeSniffer
- PHPCompatibility
- Rector
- PHP 8 Migration Guide
- MySQLi Documentation
- PhpSpreadsheet
- Composer
この記事が皆さんのPHP移行作業の参考になれば幸いです。