
PHPのレガシーコードを読み解いていると、思わず「時代を感じる…」と頷いてしまう実装に出会うことがあります。
今回は、手動でダブルクォーテーションのエスケープや包囲を行っていた独自関数 convertNl() を全廃し、現代的な fputcsv() による実装へとリファクタリングした事例をまとめました。
修正前後のコード比較
修正前(独自関数+手動フォーマット生成)
function convertNl(string $str): string
{
$str = stripslashes($str);
$str = str_replace('"', '""', $str);
return '"' . $str . '"';
}
// 書き込むデータを生成
$title = convertNl($rawTitle);
$contents = convertNl($rawContents);
$string = "$id,$category,$title,$contents,$date,$image\n";
$isSuccess = (fwrite($fp, $string) !== false);
修正後(fputcsv() への一本化)
// 書き込む配列データを準備(fputcsv が適切にエスケープとクォートを処理) $row = [$id, $category, $title, $contents, (string)$date, $image]; // CSVファイルに書き込み (PHP 8.4+ escape: '' 明示) $isSuccess = (fputcsv($fp, $row, escape: '') !== false);
主な変更点と改善の理由
1. 独自エスケープ処理(convertNl)の全廃
修正前は、ダブルクォーテーションの重ね合わせ("")や前後のクォート囲みを自作関数で行い、文字列連結でCSVの1行を生成していました。
こうした自作ロジックは、改行コードの扱い漏れや特殊文字の処理ミスによるフォーマット崩れを引き起こしがちです。修正後では、CSVフォーマット仕様(RFC 4180)に準拠した標準関数 fputcsv() にすべて委ねることで、安全かつ確実な書き込みを実現しています。
2. PHP 8.4 以降を見据えた escape: '' の明示
PHP 8.4 では、fputcsv() のデフォルトのエスケープ文字仕様(\)に関する非推奨警告が出力されるよう変更が進んでいます。標準的なCSV仕様に合わせるため、名前付き引数を用いて escape: '' を明示的に指定しています。
コラム:懐かしの magic_quotes_gpc と stripslashes()
コードの中に残っていた stripslashes($str) は、かつての magic_quotes_gpc 対策の名残(遺物) です。
当時は $_POST や $_GET などの入力値に対し、PHPの設定(magic_quotes_gpc = On)によって自動で addslashes() が適用され、クォートが \' や \" のようにエスケープされる仕組みが存在していました。そのため、「余計なお世話で付与されたバックスラッシュを stripslashes() で元に戻す」という奇妙な定型処理が広く行われていました。
現代における問題点
magic_quotes_gpcは完全に削除済み PHP 5.3 で非推奨となり、PHP 5.4 で完全に削除されました。現在の PHP 環境では自動エスケープ自体が発生しません。- データの破損(バグ)につながる 自動エスケープが行われない現代の環境で無条件に
stripslashes()を実行すると、ユーザーが意図して入力したバックスラッシュ(パス表記や正規表現など)が勝手に消去され、データが破壊されてしまいます。
まとめ
stripslashes()は即刻削除: 現代のPHPでは不要なだけでなく、データを破損させるリスクがあります。- CSV生成は
fputcsv()に任せる: 改行・カンマ・クォートのエスケープを安全に自動処理してくれる標準関数を使いましょう。
過去の互換性対策として残ったコードを整理し、標準関数へ寄せていくことで、コードの可読性と堅牢性を大幅に向上させることができます。
参考PR

