138 Views
February 22, 25
スライド概要
PHPカンファレンス名古屋2025で発表したLT資料です
消したはずのファイルが 生き残っている!? PHPのファイル操作の落とし穴 2025/02/22 PHPカンファレンス名古屋
自己紹介 ● 荒巻 拓哉 ● X: @takaram71 ● PHPer 6年目 ● 株式会社ラクス ● 名古屋大好き ○ 味仙の台湾ラーメン ○ 歌志軒の油そば
ポップアップ機能 資料請求フォームやお知らせを、自社サイトにポップアップ表示 画像: https://www.hai2mail.jp/function/popup.php
ポップアップ表示の仕組み サイト管理者 1. 所定のHTML タグを設置 3. サイトを 閲覧 2. 表示内容を 設定 4. 表示内容を 取得 サイト利用者
事件は起こった…… 開発・テストが無事完了し、社内機※へのリリース翌日…… ※ 本番環境へのリリース前に、社内のマーケティング部門が利用する環境に先行 リリースしている
大量のアラートが!!!
アラートの内容 ファイルの読み込みに失敗しました。 /path/to/user/data/960b7f00-8115-4c37-906b-9da751dc1c98 ● 上記のエラーが約2分弱だけ継続 ● 断続的に発生 ○ ポップアップの公開を停止したタイミングで発生していた
アラートの内容 ポップアップ 公開停止 2分間 のタイミングでエラーが発生 ポップアップ 公開再開 ポップアップ 公開停止 2分間
ポップアップ表示の仕組み(再) サイト管理者 1. 所定のHTML タグを設置 3. サイトを 閲覧 2. 表示内容を 設定 4. 表示内容を 取得 サイト利用者
ポップアップ表示の仕組み(再) サイト管理者 1. 所定のHTML タグを設置 3. サイトを 閲覧 2. 表示内容を 設定 4. 表示内容を 取得 設定 データ ファイル サイト利用者
ポップアップ表示の仕組み(再) サイト管理者 公開 停止 1. 所定のHTML タグを設置 3. サイトを 閲覧 2. 表示内容を 設定 4. 表示内容を 取得 設定 データ ファイル サイト利用者
例外が発生したコード(イメージ)
例外が発生したコード(イメージ) realpath() で存在 チェック
例外が発生したコード(イメージ) ファイルを 読み込み
例外が発生したコード(イメージ) ここで例外発生
例外が発生したコード(イメージ)
例外が発生したコード(イメージ)
原因は realpath() https://www.php.net/realpath realpath() は、 たとえばファイルが存在しないなどの 失敗時に false を返します。 ↑と書いているので、 realpath() が文字列を返す=ファイルが存在する ……と思っていた
Realpath キャッシュ ● realpath や require などの呼び出しを高速化するための キャッシュ ● リクエストをまたがって残る(プロセス単位) ○ PHP はシェアードナッシング(リクエスト間で状態を共有しない)が基本 ○ Realpath キャッシュは例外
今回の事象 ● ユーザー操作によってファイル削除 ● Realpath キャッシュの影響で realpath は削除前のパスを 返し続ける ○ 存在確認してるつもりが出来ていなかった
今回の事象 ● キャッシュ時間はデフォルト120秒 ● テストではアクセス数・タイミングの問題でたまたま回避 テスト: アクセス アクセス 公開停 止 キャッシュが有効 アクセス
今回の事象 ● キャッシュ時間はデフォルト120秒 ● テストではアクセス数・タイミングの問題でたまたま回避 本番: 公開停止 キャッシュが有効
対策 realpath() ではなく file_exists() で確認
結論 ● realpath() をファイルの存在確認に使ってはいけない ○ file_exists() を使おう ● 一部の状態はリクエスト間で引き継がれることもある
余談 ● clearstatcache(true) で Realpath キャッシュを削除で きる ● file_exists() も別のキャッシュがある ○ このキャッシュはリクエストごとにリセット ○ clearstatcache() でも削除