經典坑:`
<!-- ❌ 錯誤寫法:標籤間的縮排、換行全部成為 textarea 的「初始值」 -->
<textarea name="content">
這裡有縮排和換行
</textarea>
<!-- ✅ 正確寫法:內容緊貼標籤,無多餘空白字元 -->
<textarea name="content">這裡沒有多餘空白</textarea>
本質: 瀏覽器將 `
模板引擎 (Blade/Twig/Smarty/PHP 原生) 輸出時**不要在標籤間換行縮排**:
<!-- PHP 原生 -->
<textarea name="content"><?= htmlspecialchars($content) ?></textarea>
<!-- Blade -->
<textarea name="content">{{ $content }}</textarea>
<!-- Twig -->
<textarea name="content">{{ content|raw }}</textarea> {# 若已轉義用 raw #}
原則:**動態內容直接貼緊標籤**,靜態預設值同理。
雖然前端修正通常足夠,但建議在控制器/服務層統一清洗,防禦手工構造請求、爬蟲、API 直連等繞過前端的情況:
<?php
function cleanTextareaInput(string $input): string {
// 1. 統一換行符為 \n (跨平台兼容)
$input = str_replace(["\r\n", "\r"], "\n", $input);
// 2. 去除首尾空白字元 (空格、Tab、換行、垂直製表等)
$input = trim($input);
// 3. 可選:壓縮連續空行 (保留段落結構)
// $input = preg_replace('/\n{3,}/', "\n\n", $input);
return $input;
}
// 使用
$cleanContent = cleanTextareaInput($_POST['content'] ?? '');
// 入庫 $cleanContent
?>
關鍵點:
讀出資料庫內容顯示在 `
` (非表單) 時:
<?php
// 方案 A: nl2br() 轉
(簡單但產生混合內容)
echo nl2br(htmlspecialchars($content));
// 方案 B: CSS 保留原始換行 (推薦,語義純粹)
?>
<div class="content-box" style="white-space: pre-wrap; word-wrap: break-word;">
<?= htmlspecialchars($content) ?>
</div>
CSS `white-space: pre-wrap` 完美保留空格、Tab、換行,且自動換行,無需轉 `
`,最符合現代標準。
| 環境 | 換行符 | PHP 常量 |
|---|---|---|
| Windows (CRLF) | `\r\n` (0x0D 0x0A) | `PHP_EOL` (運行環境相關) |
| Linux/macOS (LF) | `\n` (0x0A) | `"\n"` |
| 舊 Mac (CR) | `\r` (0x0D) | `"\r"` |
資料庫建議**統一存儲 `\n` (LF)**,前端 `
遵循「前端不產生垃圾字元、後端養成清洗習慣、顯示層用 CSS 語義化」,徹底告別 textarea 空白困擾。