導入
Web開発の現場において、ユーザーが入力したテキスト(例えばブログの投稿やお問い合わせ内容)をHTMLとして画面に表示する際、改行コードをそのまま出力してもブラウザ上では改行されません。かといって、単に全ての改行をbrタグに置換すると、文章の構造(段落)が失われ、見た目が悪くなることがあります。本記事では、PHPでテキストを論理的な段落(pタグ)と改行(brタグ)に自動変換し、かつセキュリティを考慮したHTML生成手法を解説します。
基礎知識
PHPには文字列をHTMLに変換するための便利な関数がいくつか存在します。
htmlspecialchars()は、特殊文字(<, >, &, ” など)をHTMLエンティティに変換し、XSS(クロスサイトスクリプティング)を防ぐために必須の関数です。
nl2br()は、改行コード(\n)の前にbrタグを挿入する関数です。
preg_split()は、正規表現を用いて文字列を分割します。今回は「空行(改行が2つ以上連続する箇所)」を段落の区切りとして利用します。
実装/解決策
実務では、入力されたテキストをまず安全な状態(エスケープ)にし、その後に構造化するのが定石です。
手順は以下の通りです。
1. 正規表現 \R\R+ を用いて、2つ以上の改行がある箇所でテキストを分割します。
2. 分割された各ブロックをループ処理します。
3. 各ブロックに対して htmlspecialchars() を適用し、セキュリティを確保します。
4. 最後に nl2br() で残りの改行をbrタグに変換し、全体をpタグで囲みます。
サンプルプログラム
以下のコードは、汎用的な関数として実装したものです。そのままコピー&ペーストして利用可能です。
- @param string $text 変換対象のテキスト
- @param bool $xhtml XHTML形式で出力するかどうか
- @return string
/
function convertTextToHtml(string $text, bool $xhtml = true): string
{
// 2つ以上の連続する改行(\RはUnicode改行に対応)で段落を分割
$paragraphs = preg_split(“/\R\R+/”, $text, -1, PREG_SPLIT_NO_EMPTY);
$output = [];
foreach ($paragraphs as $paragraph) {
// まずHTMLエスケープ処理を行い、XSS対策を行う
$escaped = htmlspecialchars($paragraph, ENT_QUOTES, ‘UTF-8’);
// 改行をbrタグに変換し、pタグで囲む
$output[] = ‘
‘ . nl2br($escaped, $xhtml) . ‘
‘;
}
return implode(“\n”, $output);
}
// 動作確認用データ
$input = “これは段落1です。\n2行目です。\n\nこちらは段落2です。”;
echo convertTextToHtml($input);
?>
応用・注意点
実務でこの手法を用いる際の注意点が2つあります。
一つ目は文字エンコーディングの指定です。htmlspecialchars()の第3引数には必ず ‘UTF-8’ を明示してください。これを忘れると、環境によって文字化けが発生するリスクがあります。
二つ目は連続するbrタグの回避です。無理やり全ての改行をbrに変換しようとすると、不要な空行が大量に生成され、ソースコードが肥大化します。上記のように「段落単位で処理する」ことで、ソースコードの可読性を保ちつつ、適切な余白を維持したマークアップが可能になります。もし、さらに複雑な装飾(リストや見出し)が必要な場合は、Markdownパーサーライブラリ(Parsedownなど)の導入を検討するのが、現代的なPHP開発の標準的な選択肢となります。