作者と連絡が取れず、Gitの履歴もなく、本番サーバーのソースだけが残っている。そんな、いわば「野良」の PHP 7系アプリを引き継いだ技術者に向けた記事である。動作に必要なファイルを探し、個人情報を切り離し、既存の業務を維持したまま新環境へ移すには何が必要か。人間1人と複数のAIエージェントで PHP 7.4 のアプリを PHP 8.3 へ改修した経験から、手順とつまずきを紹介する。
- ソースとデータを整理し、匿名化した材料で検証できる環境を用意する。
- 既存機能を維持する範囲と完了条件を、人が先に決めて AI に渡す。
- HTTP応答に加え、普段の利用者に業務の操作を試してもらう。
1 出発点と移行の範囲
対象は、日々の業務に使われていた業務ポータルシステムだった。作者とは連絡が取れず、Git などの変更履歴を管理する仕組みもなく、本番サーバー上のソースだけが残っていた。実装の流儀は統一されておらず、素の PHP と一部のフレームワークが混在していた。
脆弱性対応をきっかけにサービスを停止し、PHP 8.3 の新サーバーへ移すことになった。再開を急ぐ一方で、画面・操作手順・業務ルールはできるだけ維持する必要があった。ここでの作業目標は、既存機能を移設先で動かし、人が確認を始められる状態にすることだった。
対象はアプリA(受付・入力フォームを中心とした業務ポータル)とアプリB(データ照会・確認画面)である。素のPHP、古いライブラリ、一部に組み込まれたフレームワークが混在する環境で、依存関係を調べながら改修を進めた。
作業は、人間1人と複数のAIエージェントの体制で行った。人が方針や優先順位を決め、AIが指示書の作成、実装、検証を分担した。AIによる工数の試算は約100人日だったが、対応開始から7日後には、本番サーバーで動作確認を行える状態になった。
| 対象 | 構成と確認すべき点 |
|---|---|
| アプリA | 素の PHP と PEAR(既存ライブラリ群)。transactions/appfiles/ には別の CakePHP アプリがあった。preview-copy/ は単体テストではなく、旧検証環境の複製だった。 |
| アプリB | CodeIgniter を利用。フレームワーク本体の framework-lib/ がリポジトリ(コードの保管場所)の外にあった。 |
| 移設先 | クラウドの IaaS(仮想サーバー基盤)上の Ubuntu 24.04。Apache 2.4 と PHP-FPM 8.3(PHPを実行するプロセス管理機構)を組み合わせた。 |
2 全体の流れ
最初に、作業を次の七つに分けておく。匿名化の検討は早い段階で始めるが、DBの実際の加工にはローカルの Docker 環境が必要になる。工程1と2は行き来しながら進める。
| 工程 | 目的 | 人がやること | AIがやること |
|---|---|---|---|
| 1 匿名化 | 検証材料から個人情報を切り離す | 対象を確認し、DBを匿名化する | DB構造から候補を挙げ、匿名化済みデータを取り込む |
| 2 Docker | ローカルで試せる環境を作る | 必要な環境と接続先を決める | 環境を整備し、構文とHTTPを確認する |
| 3 Git | 変更を追跡できるようにする | 登録する材料と秘密情報を確認する | 既存の差分を守りながら修正する |
| 4 新サーバー | 戻せる手順で構築する | 接続・公開範囲を決める | 操作を記録し、変更前後を確認する |
| 5 PHP対応 | 既存機能を維持して移行する | 変更範囲と完了条件を決める | 互換性を修正し、別の役割で検証する |
| 6 デプロイ | 実行環境に配置する | 配置先と権限を確認する | 配置・依存導入・動作確認を進める |
| 7 利用者確認 | 業務の操作が成立するか確かめる | 普段の操作で試す | 不具合の原因を調べ、必要な修正をする |
3 ソースと DB の匿名化
目的
改修に必要な材料を残しながら、個人情報や接続情報を AI に渡す範囲から切り離す。匿名化は、コードをリポジトリへ登録する前にも確認しておきたい作業である。
やったこと
本番サーバーのファイルを手元に取得し、一時ファイルや改修に不要なものを分けた。メールアドレスやよくある氏名で検索し、個人情報を含む可能性のあるファイルを洗い出した。必要なファイルは awk・sed・Python を使って加工した。
新サーバーへ送るソースからは、CSV・Excel・SQL・ログ・圧縮ファイル・バックアップ、アップロード済みデータ、キャッシュ、旧検証環境の複製などを除外した。一方、Composer(PHPの依存ライブラリ管理ツール)が導入するライブラリや、動作に必要な設定ファイルは別途扱った。設定に残る旧DBの接続情報は値を表示しないようにした。
DBは Docker に再現し、人が匿名化した。DDL(テーブルの構造を定義するSQL)を AI に読ませ、個人情報が入りそうな列の候補を挙げてもらったうえで、SQLの UPDATE 文で加工する。加工後にダンプ(DBをファイルへ書き出したもの)を取り、文字列検索で残存を調べた。
AIに渡した匿名化済みSQLは、既存DBへ直接入れず、ネットワークを切った別の Docker プロジェクトに取り込んだ。compose.reference.yaml で環境を分け、取り込み後は読み取り専用にした。列名と列順が元のDDLと一致することも確認した。
実際のコマンド
次は Git Bash で使ったファイル検索と、DB構造を取り出すコマンドである。[ユーザー名] と [データベース名] は実際の値に置き換える。--no-data は構造だけを出力するため、データを含むダンプの取得とは区別する。
grep @gmail.com * -rl
grep 鈴木 * -rl
mysqldump -u [ユーザー名] -p --no-data [データベース名] > ddl.$$.sql
匿名化したダンプを次のように検索した。検索に一致しないことだけで、すべての個人情報を除去できたとは判断しない。
grep "@gmail.com" dump.sql
grep "田中" dump.sql
参照用DBには、用意済みの独自スクリプトを使った。取り込みスクリプトは空でないDBへの上書きを拒否する設計だった。
Start-Anon-Reference.ps1 # 参照用DBの起動
python tools/load-reference-db.py # 取り込み(空でないDBへの上書きは拒否)
Stop-Anon-Reference.ps1 # 参照用DBだけを停止
つまずいたこと
パスワードファイルの末尾が CRLF(Windowsで使われる改行形式)だったため、参照用DBへの認証に失敗した。データを入れる前に停止しており、秘密の値を表示せず、改行形式だけを確認して LF に直した。
教訓
除外対象と動作に必要なファイルを、同じ一覧で確認する。ファイルの種類だけで一律に除外すると、後で必要な帳票やPDFを取りこぼす。DBでは、匿名化した内容の確認と、取り込み後の構造確認を分けると、何を確かめたのかが明確になる。
4 ローカルの Docker 検証環境
目的
Docker(アプリの実行環境をコンテナとして用意する仕組み)で PHP 8.3 とDBを動かし、移設前に不具合を再現できるようにする。
やったこと
最初の計画ではローカル検証環境の整備が不足していた。人が必要性を指摘し、利用するポートとIPの情報を渡した。できあがった環境は PHP 8.3 FPM、Apache 2.4、MariaDB 10.11、Mailpit(送信メールを捕捉するツール)、外部APIのスタブ(実際の接続先の代わり)で構成した。
元のソースは読み取り専用でマウントし、設定だけを Docker 側で上書きした。アプリBは localhost:8884、アプリAは localhost:8885、メール確認は localhost:8886 を使った。
実際のコマンドとプロンプト
人が出した指示は短かったが、その前に対象とポートの情報を共有していた。
AstraでDocker環境の整備を始めてください
準備・起動・確認・停止を独自の PowerShell スクリプトにまとめた。以下は作成済みスクリプトの一覧である。
Initialize-Local.ps1 # 初回の準備
Start-Local.ps1 # 起動
Test-Local.ps1 # 環境確認(51項目)
Stop-Local.ps1 # このComposeプロジェクトだけを停止
Compose(複数のコンテナをまとめて扱う仕組み)の片付けには、次を使った。データ用の volume と資格情報は残る。
docker compose --profile test down
つまずいたこと
アプリAを最初に開くと HTTP 500(サーバー内部のエラー)になった。原因は、文字列を波括弧で取り出す古いPHPの書き方だった。環境を作ったことで、互換性の問題を具体的なエラーとして確認できた。
教訓
コンテナが起動しただけでは、アプリの確認は終わらない。構文検査、ページの応答、ログを順に確かめる。外部APIやメールの接続先を分けておくことも、検証環境を準備する仕事に含める。
5 Git 管理とリポジトリ
目的
匿名化後のソースを非公開リポジトリに置き、何を変更したかを追えるようにする。本番にしかなかったコードを、差分を比較しながら改修できる材料にする。
やったこと
PHP 8.3 対応用の非公開リポジトリを用意し、匿名化したプログラムを登録した。複数のAIが作業する際には、すでに修正した内容を消さないことも指示に含めた。
実際のプロンプト
アプリAへの指示のうち、作業中の差分を守るための一文である。
- 既存の未コミット差分を保存する。一括reset・差分の一括破棄はしない。
つまずいたこと
ソースを登録しても、動作に必要なものがすべてそろったわけではなかった。アプリBのフレームワーク本体はリポジトリの外にあり、後の利用者確認では、Gitに入っていなかった帳票ひな形の不足も見つかった。
教訓
登録前に秘密情報を確認するとともに、登録したソースと動作に必要な配布物を突き合わせる。改修途中の差分も作業の成果なので、AIに一括で初期状態へ戻させない。
6 新サーバーを安全に構築する
目的
設定を誤ったときにも戻せるようにして、新しい実行環境を作る。クラウドは AWS・GCP・さくらのクラウドのどれでもよい。今回の実例では、クラウドの IaaS に Ubuntu 24.04 を用意した。
やったこと
AIのサーバー操作は専用の実行窓口を通し、目的・コマンド・終了コード・出力の行数とハッシュ(内容を識別する値)を server-ops.log に記録した。まず既存状態を読み取り、Apache と PHP-FPM を導入して連携した。パッケージの変更記録で脆弱性修正を確認し、PHP設定や証明書も整えた。
SSHと ufw(ファイアウォール)は、誤ると自分が接続できなくなる。そこで変更前に「5分後に元へ戻すタイマー」を設定し、新しい接続で入れることを確認してから止めた。変更前の状態と戻す手順を先に用意することが、この工程の要点である。
WAF(Webへの不正なアクセスを検知する仕組み)の SiteGuard は監視モードから導入した。試験用の VirtualHost(Apacheでサイトを分ける設定)は接続範囲を限定した。アプリA・Bには、業務の担当者向けに Basic認証付きの確認用ドメインも用意した。
実際のコマンド
読み取り中心の初期確認から抜粋する。
hostnamectl | grep -E "hostname|Operating|Kernel|Virtualization"
nproc; free -m; df -h /
ip -br link; ip -br addr; ip route
ls -l /etc/netplan
sudo -n true && echo SUDO_NOPASSWD_OK || echo SUDO_NEEDS_PASSWORD
ss -ltn
つまずいたこと
ソースの転送では、一時ファイルを削除する手順が AI ツールの安全確認で止まった。そこで、ローカルで作った tar(複数ファイルをまとめたアーカイブ)を標準入力で送り、一時ファイルを作らず展開する形に変えた。送る前のハッシュを記録し、受信側でもハッシュを出すようにした。
教訓
設定の正しさと、変更後に接続できることは別に確認する。元へ戻す手順、接続確認、操作記録を、変更コマンドと一緒に準備しておく。
7 AI による PHP 8.3 対応
目的
移設で動かなくなる箇所を直し、既存の画面と業務ルールを維持する。AIが担当する範囲と、人が合格を判断する条件を先にそろえる。
やったこと
Claude Code と Codex(Astra)を併用した。初めは Codex が指示書を作り、Claude Code が修正し、Codex が検証する役割分担にした。修正側にはファイルの読み書きだけを渡し、シェルなどの操作や秘密設定の読み取りは制限した。
Claudeが「完了」と返しても、その報告だけで合格にはしなかった。Codexが Docker で構文検査、回帰テスト(変更前の機能が壊れていないかの試験)、HTTP確認をやり直した。
途中で作業が長引き、意図した範囲から離れていたため、人が方針を修正した。Codexに担当別の指示書を作らせ、Git Bashでそれぞれのリポジトリから起動した Claude Code に渡した。役割を増やすだけでなく、何を変えず、どこまで確認したら完了なのかを書き直した。
実際のプロンプトとコマンド
アプリAへの指示から、変更範囲と完了条件を抜粋する。引用中の「Web環境担当」は、サーバーのWeb環境を整える役割のAIエージェントを指す。この指示は移設作業の範囲を固定するもので、見つかった問題の報告と、公開前に対応すべきかの判断は別に行う。
- 既存の管理画面、受付、入力フォームのコード・項目・業務ルールを維持する。これまで動作した状態と修正済みの差分を保存する。
- 移設先 /srv/webapps/app-a/ で必要なDB接続、ROOT_PATH等のパス、PEAR等の依存、URL、生成ファイルの場所を確認し、Web環境担当へ伝える。
- /portal/...が拒否される問題、CSV・ZIPの書込み条件などは、まずWeb環境担当に環境を合わせてもらう。回避のために全テンプレートやURLを書き換えない。
- クラウド配置後、既存のログイン・管理メニュー・受付窓口・入力フォームの入口を開き、移設で生じる停止箇所を確認する。必要なPHP互換性やパスの修正だけを行う。
- 既存のログイン方法、パスワード方式、画面項目、操作手順、業務ルールを変えない。
- 変更は、移設で動かない原因となるパス・接続・依存・PHP互換性等の必要最小限にする。
- 既存の未コミット差分を保存する。一括reset・差分の一括破棄はしない。
完了条件は「クラウド上で、人間が既存の画面を開いて動作確認を始められる状態」です。Dockerで動いたこと、手順書を書いたことだけでクラウドへの配置完了とはしません。
新サーバーでは、各アプリのPHPファイルを構文検査した。次は Bash での実例である。失敗したファイルがあっても走査を続け、Parse error と Fatal error を集計する。警告や業務上の不具合まで検出するものではない。
cd /srv/webapps
for d in app-a app-b/public-site app-b/appcode app-b/framework-lib; do
out=$(find $d -name '*.php' -print0 \
| xargs -0 -n1 -P2 sh -c 'php -d display_errors=stderr -l "$1" 2>&1 || true' _ \
| grep -E 'Parse error|Fatal error')
echo "=== $d : php files=$(find $d -name '*.php' | wc -l) errors=$(echo "$out" | grep -c .)"
done
修正対象には次のようなものがあった。実例で具体的に示された直し方と、修正対象として挙がっただけのものを区別する。
| 症状 | 原因 | 直し方と確認点 |
|---|---|---|
| PHPの構文エラー | $str{0} のように波括弧で文字列へアクセスする古い構文 | PHP 8に対応する構文へ修正し、構文検査をやり直す。 |
| 初期化が実行されない | クラス名と同名のメソッドをコンストラクタにする旧形式 | __construct から既存の初期化メソッドを呼び、元のメソッドは残した。 |
| 静的な呼び出しと宣言が合わない | singleton() が非静的メソッドとして宣言されていた | 実例では静的メソッドとして宣言し直した。 |
| 古いライブラリが構文検査で問題になる | PEAR Auth に =& new の参照代入が残っていた | 古い構文を修正する。具体的な差分はここには掲載していない。 |
| 関数名が衝突する | 独自の mb_str_pad とPHPの組み込み関数が同名 | 独自実装と組み込み関数の衝突を解消する。具体的な差分はここには掲載していない。 |
mPDFの日本語フォント指定も修正対象になった。これは上の構文や呼び出し規約とは別に、生成したPDFを確認する必要がある箇所だった。
つまずいたこと
最初の回帰テストでは、本物の PEAR があるのに仮のクラスを作ってしまい、二重定義で失敗した。AIの説明とコードが食い違っていたため、確認したい対象を仮の実装に置き換えず、実際の依存ライブラリを使う方針で直させた。
教訓
AIには、変更してよい範囲、維持する動作、使ってよい環境、完了条件を同じ指示書で渡す。説明を読んだ後は差分と実行結果を見る。テストが通っても、何を対象として試したのかが違えば、期待した検証にはならない。
8 ソースの配置とサーバー上の確認
目的
デプロイ(コードを実行先へ配置すること)では、ソースだけでなく、依存ライブラリ・設定・生成ファイルの置き場所までそろえる。サーバー上で確認できる状態を作り、利用者の試験につなげる。
やったこと
アプリA・Bのソースを、個人情報を含みうるファイルを除いたアーカイブにまとめて送った。動作に必要な依存ライブラリや設定も確認し、サーバー上の配置先・DB接続・URL・CSVやZIPの書き込み条件を合わせた。
最初の配置では ubuntu を所有者、Webプロセスの www-data をグループとし、ディレクトリは2750、ファイルは640にした。これはソースを読み取って試す段階の権限であり、アプリが生成ファイルを書ける状態まで整えるには、出力先を別途確認する必要がある。
実際のコマンド
次はアプリAの初回配置に使った処理で、サーバー側の Bash で実行した。標準入力からtarアーカイブが届くことを前提としているため、単独で貼り付けて使うコマンドではない。送信側の操作は省略している。配置先が存在する場合は停止する。
D=/srv/webapps/app-a
if [ -e $D ]; then echo "$D already exists, abort"; exit 40; fi
sudo install -d -o ubuntu -g www-data -m 2750 $(dirname $D) $D
tee >(sha256sum | sed 's/^/received sha256: /' >&2) \
| sudo tar -C $D --no-same-owner --no-same-permissions -xf -
sudo chown -R ubuntu:www-data $D
sudo find $D -type d -exec chmod 2750 {} +
sudo find $D -type f -exec chmod 640 {} +
配置後は、サーバー内からしか開けない試験用サイトでHTTP応答とPHPのエラーログを確認した。以下はアプリAの入口を確認したコマンドで、ドメインとURLパスは仮名にしている。
UA='Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)'
curl -s -o /tmp/http-check.out -A "$UA" \
-w '%{http_code} size=%{size_download} redirect=%{redirect_url}\n' \
--resolve app-a.example.test:80:127.0.0.1 http://app-a.example.test/entry.php
つまずいたこと
URLやファイル出力の問題では、アプリと環境のどちらを直すかが課題になった。アプリAへの指示では、まずWeb環境を担当するAIに設定を合わせてもらい、互換性やパスの修正は必要最小限にする方針を明確にした。
教訓
ソースを置いたことと、アプリが業務に必要なファイルを読み書きできることを分けて確認する。共通の配置規約がないアプリでは、生成物や設定の場所をコードと照らし合わせて調べる必要がある。
9 利用者による動作確認
目的
普段アプリを使っている人に、いつもの業務の操作で確かめてもらう。HTTP 200(リクエストへの正常な応答)が返ることと、登録・帳票・外部サービスとの連携などの業務が成立することを分けて判断する。
やったこと
確認依頼を作るAIと、実際に改修していたAIは別だった。そのため、確認依頼を書く前に、記録とサーバーで確かめた事実を問い合わせた。確認用URL、アクセス制限、利用するDBが本番・匿名化済み・空のどれかをそろえ、分からないことは未確認とした。
実際のプロンプトと設定
確認依頼のための質問から抜粋する。
次の質問に、記録とサーバーで確かめた事実だけで答えてください。分からないことは「未確認」と書いてください。
パスワード・鍵・.env や config の値は書かないでください。
- 2 つのサイトは、今どのサーバーで動いていますか。PHP と CodeIgniter・CakePHP などの版も教えてください。
- 業務の担当者が確認に使う URL を、画面ごとに教えてください。
- その URL は、どこから開けますか。IP の制限、Basic 認証などはありますか。
- 確認に使う DB は、本番、匿名化したもの、空のもの、のどれですか。
利用者からは、管理メニューの /portal/... が開けないという報告があった。旧 .htaccess(ディレクトリ単位のApache設定)の書き換えが新環境でループしていたため、確認用 VirtualHost に次の3行を追加した。これはその構成での修正例であり、すべてのサイトへ一律に追加する設定ではない。
RewriteRule ^/portal(/.*)?$ /portal.php$1 [END]
RewriteRule ^/(entry|survey)(/.*)?$ /$1.php$2 [END]
RewriteRule ^/(dashboard|signout|records)(/.*)?$ /portal.php/$1$2 [END]
つまずいたこと
Dockerの試験では見つからず、利用者の操作で次の不具合が分かった。
| 見つかった不具合 | 原因と対応の記録 |
|---|---|
| 任意の入力項目を空欄にすると登録に失敗する | 空欄での操作に問題が見つかった。具体的な修正内容や再試験結果はここでは断定しない。 |
| 帳票(Excel)の出力がHTTP 500になる | Excelの帳票ひな形がGitに入っておらず、人が旧本番から原本を探して復元した。匿名化の時に作業者が消していた。 |
| マニュアル等の PDF ファイルを開くとトップへ戻る | PDFが配置されていなかったため、旧本番の原本から復元した。 作業者が使っていないと判断してリポジトリに入れていなかった。 |
| 外部サービスからの戻り先が合わない | 新環境に合わないURLが使われていた。環境に応じて戻り先を選ぶように修正した。もともとのプログラムがURLをソースコード内にハードコーディングしていた。 |
教訓
画面の入口だけでなく、空欄の登録、ダウンロード、外部連携から戻る操作を確認する。匿名化や配布対象の整理で除いたファイルにも、業務で必要なものがある。コードの修正だけでなく、配布物がそろっているかも利用者の報告と突き合わせる。
ここで述べたのは、試験環境の整備、互換性の修正、配置後に見つかった不具合への対応である。すべての業務が合格したことや、一般公開を再開してよいことを、HTTP応答やAIの完了報告だけで判断しない。
10 AI と進めるときの教訓
- 最初に「既存機能を維持する」と決める。変更してよい箇所を狭めると、環境差の問題を大きな改修で回避する流れを防ぎやすい。
- AIへ渡す前に、ソース・DB・設定の秘密情報を分ける。匿名化の検索と構造の確認は、別の確認結果として残す。
- 実装と検証の役割を分ける。AIの説明だけで判断せず、差分、実際の依存ライブラリ、実行結果を突き合わせる。
- 失敗したときの戻し方を先に用意する。バックアップ、設定検査、自動復旧のタイマーを変更の手順に含める。
- 配布物まで確認する。Gitにないフレームワーク本体、帳票、PDF、環境設定も、アプリを動かすための材料である。
- 確認した環境と範囲を明示する。Dockerで動くこと、サーバーへ配置できたこと、業務操作ができたことを区別する。
- 最後は利用者の操作で確かめる。未確認の点を残したまま「完了」とまとめず、何を次に確認するかを共有する。
付録A プロンプトのひな形
実際の指示から、対象や環境を穴埋めにしたひな形である。<アプリ名> などを置き換え、変更範囲と完了条件を確認してから渡す。
既存機能を維持して移設する
対象:
<アプリ名>担当の<AI名>
- 既存の管理画面、受付、入力フォームのコード・項目・業務ルールを維持する。これまで動作した状態と修正済みの差分を保存する。
- 移設先
<配置先パス>で必要なDB接続、パス、依存ライブラリ、URL、生成ファイルの場所を確認し、<サーバー担当>へ伝える。- URLが拒否される問題やCSV・ZIPの書込み条件などは、まず
<サーバー担当>に環境を合わせてもらう。回避のために全テンプレートやURLを書き換えない。- 配置後、既存のログイン・管理メニュー・受付窓口・入力フォームの入口を開き、移設で生じる停止箇所を確認する。必要なPHP互換性やパスの修正だけを行う。
既存のログイン方法、パスワード方式、画面項目、操作手順、業務ルールを変えない。既存の未コミット差分を保存し、一括reset・差分の一括破棄はしない。
完了条件は「<移設先環境>で、人間が既存の画面を開いて動作確認を始められる状態」です。Dockerで動いたこと、手順書を書いたことだけで配置完了とはしません。
利用者への確認依頼を準備する
次の質問に、記録とサーバーで確かめた事実だけで答えてください。分からないことは「未確認」と書いてください。
パスワード・鍵・.env や config の値は書かないでください。
<対象サイト>は、今どのサーバーで動いていますか。PHPとフレームワークの版も教えてください。- 業務の担当者が確認に使うURLを、画面ごとに教えてください。
- そのURLは、どこから開けますか。IPの制限、Basic認証などはありますか。
- 確認に使うDBは、本番、匿名化したもの、空のもの、のどれですか。
付録B 用途別のコマンド集
本文で使用した短いコマンドを用途別にまとめる。長い権限設定や構文検査は、前提条件を含めて本文の該当節を参照する。例示名を置き換えることと、独自スクリプトを準備することが必要である。
個人情報の候補と残存を探す
grep @gmail.com * -rl
grep 鈴木 * -rl
grep "@gmail.com" dump.sql
grep "田中" dump.sql
DBの構造を取り出す
mysqldump -u [ユーザー名] -p --no-data [データベース名] > ddl.$$.sql
ローカル環境と匿名化済みDBを扱う
Initialize-Local.ps1 # 初回の準備
Start-Local.ps1 # 起動
Test-Local.ps1 # 環境確認(51項目)
Stop-Local.ps1 # このComposeプロジェクトだけを停止
docker compose --profile test down
Start-Anon-Reference.ps1 # 参照用DBの起動
python tools/load-reference-db.py # 取り込み(空でないDBへの上書きは拒否)
Stop-Anon-Reference.ps1 # 参照用DBだけを停止
サーバー上でHTTP応答を確認する
UA='Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)'
curl -s -o /tmp/http-check.out -A "$UA" \
-w '%{http_code} size=%{size_download} redirect=%{redirect_url}\n' \
--resolve app-a.example.test:80:127.0.0.1 http://app-a.example.test/entry.php
初期サーバー確認は第6節、構文検査のループは第7節、アーカイブによる初回配置と権限設定は第8節、Apacheの書き換えルールは第9節に掲載した。
筆者について・ご相談の窓口
フリーランスのエンジニアです。この記事のような、管理されていない古い PHP アプリの移行を手伝っています。
- 記事の内容についての質問は、コメント欄にどうぞ。同じことで困っている方の参考にもなります。
- 個別のご相談は、次のフォームからご連絡ください。初回の返信(お手伝いできるか、どの形が合いそうか)は無料です。その先の調査や作業は有償で、内容に応じてお見積りします。
お手伝いできることの例:
- ソースを拝見し、PHP 8.3 での非互換の一覧と移行の見積りを作る
- ローカルの検証環境づくりと、AI への指示書づくり
- 新サーバーへの移行手順づくりとレビュー
フォームには、パスワードや顧客の情報、社内の秘密情報は書かないでください。すべてのご相談への返信をお約束するものではありません。