首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP nl2br 與 nl2p 換行轉換深度解析:HTML 輸出、段落語意化、XSS 防護與自定義函數

     編輯:PHP 相關知識

PHP nl2br 與 nl2p 換行轉換深度解析:HTML 輸出、段落語意化、XSS 防護與自定義函數

從資料庫讀取的文字內容常含 \n 換行,直接輸出 HTML 會合併為單行。nl2br() 簡單插入 <br>,但語意不佳;nl2p() 將換行轉為 <p> 段落,支援 CSS 排版。本文詳細對比兩者、提供生產級 nl2p 實作、XSS 防護與 CSS 配合建議。

一、nl2br() 內建函數

<?php
$text = "第一行\n第二行\n第三行";
echo nl2br($text);
/* 輸出 HTML:
第一行<br />
第二行<br />
第三行
*/
?>
  • **行為**:在每個 \n (含 \r\n, \r) **前**插入 <br /> (XHTML) 或 <br> (HTML5)。
  • **不轉義 HTML 實體**:若內容含 <script> 會直接輸出 → **XSS 風險**。
  • **無段落語意**:CSS 難控制段落間距、首行縮進。

二、基礎 nl2p 實作 (簡易替換)

<?php
function nl2p_simple($text) {
    return '<p>' . str_replace("\n", '</p><p>', $text) . '</p>';
}
?>

缺點:連續多個 \n 產生空 <p></p>;單換行無法區分段落與換行。

三、生產級 nl2p 函數 (支援單/雙換行、HTML 清理、XSS 防護)

<?php
/**
 * 將純文字轉為語意化 HTML 段落
 * @param string $text      輸入文字
 * @param bool   $lineBreak 單換行是否轉 <br> (true) 或合併段落 (false)
 * @param bool   $xml       <br /> (true) 或 <br> (false)
 * @return string
 */
function nl2p(string $text, bool $lineBreak = true, bool $xml = true): string {
    // 1. 移除既有 HTML 標籤 (防止雙重包裹與 XSS)
    $text = strip_tags($text, '



'); // 可保留少數安全標籤 // 2. 統一換行符為 \n $text = str_replace(["\r\n", "\r"], "\n", $text); // 3. 修剪首尾空白 $text = trim($text); if ($text === '') return ''; if ($lineBreak) { // 模式 A:雙換行 = 新段落,單換行 =
// 先將連續 2+ \n 替換為段落分隔標記 $text = preg_replace('/\n{2,}/', "\n\n", $text); // 正規化多重空行 // 單換行轉
$text = preg_replace('/([^>])\n([^<])/', '$1<br' . ($xml ? ' /' : '') . '>$2', $text); // 雙換行包裹段落 $paragraphs = explode("\n\n", $text); } else { // 模式 B:所有換行皆為新段落 $paragraphs = preg_split('/\n+/', $text); } // 4. 包裹

標籤 $html = ''; foreach ($paragraphs as $p) { $p = trim($p); if ($p !== '') $html .= '<p>' . $p . '</p>'; } return $html; } // 測試 $input = "標題行\n\n正文第一段\n單換行\n\n正文第二段"; echo nl2p($input); /* 輸出: <p>標題行</p> <p>正文第一段<br />單換行</p> <p>正文第二段</p> */ ?>

四、XSS 防護完整策略

  1. 輸入端:儲存前 strip_tags() 或 htmlspecialchars() (視業務是否允許富文本)。
  2. 輸出端:nl2p 內部已 strip_tags;若允許部分標籤 (如 <b><i>),用 HTMLPurifier 白名單過濾。
  3. CSP 標頭:Content-Security-Policy: default-src 'self'; script-src 'self' 纵深防禦。

五、CSS 樣式建議

/* 重置瀏覽器預設 margin */
p { margin: 0 0 1em; line-height: 1.6; }
p + p { margin-top: 1em; } /* 段落間距 */
/* 首行縮進 (中文) */
p { text-indent: 2em; }
p:first-child { text-indent: 0; }
/* 代碼區塊保持預格式 */
pre { white-space: pre-wrap; word-break: break-all; }

六、對比總結

特性nl2br()nl2p() (生產級)
語意標籤<br> (行內)<p> (區塊)
CSS 控制困難靈活 (margin, indent, line-height)
雙換行處理兩個 <br>分離段落
單換行選項無可選 <br> 或合併
XSS 防護無 (需自行 htmlspecialchars)內建 strip_tags + 選項
適用場景簡單單行輸出、代碼片段文章、評論、郵件內容、CMS
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved