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

PHP 批量檢測並移除 UTF-8 文件 BOM 頭完整腳本

     編輯:PHP 相關知識

PHP 批量檢測並移除 UTF-8 文件 BOM 頭完整腳本

UTF-8 BOM (Byte Order Mark, EF BB BF) 會導致 PHP 輸出時在文件開頭產生不可見字符,引發「headers already sent」、圖片輸出損壞、Session 啟動失效等疑難雜症。本文提供一個可直接運行的 CLI/WEB 兼容腳本,支援遞歸掃描目錄、自動備份、乾運行模式、彩色輸出,幫你徹底清理專案中的 BOM 隱患。

BOM 危害速覽

  • HTTP 頭輸出失敗:header()、session_start()、setcookie() 之前有輸出。
  • 圖片/二進制流損壞:驗證碼、圖表、文件下載輸出前混入 BOM。
  • XML/JSON 解析錯誤:API 回包開頭帶 BOM 導致客戶端解析失敗。
  • 頁面頂部莫名空白行:瀏覽器渲染時顯示不明字符或留白。

核心檢測邏輯

function hasBom(string $content): bool {
    return strlen($content) >= 3 
        && ord($content[0]) === 0xEF 
        && ord($content[1]) === 0xBB 
        && ord($content[2]) === 0xBF;
}

function removeBom(string $content): string {
    return hasBom($content) ? substr($content, 3) : $content;
}

完整掃描清理腳本 (del_bom.php)

<?php
/**
 * UTF-8 BOM 批量檢測與移除工具
 * 用法:
 *   CLI: php del_bom.php [目錄] [--dry-run] [--backup]
 *   WEB: 訪問 https://yourhost/del_bom.php?dir=目錄&dry=1&backup=1
 */
declare(strict_types=1);

$baseDir = $argv[1] ?? ($_GET['dir'] ?? '.');
$dryRun  = in_array('--dry-run', $argv) || isset($_GET['dry']);
$backup  = in_array('--backup', $argv) || isset($_GET['backup']);

$baseDir = realpath($baseDir);
if (!$baseDir || !is_dir($baseDir)) {
    die("目錄不存在: $baseDir\n");
}

echo "掃描目錄: $baseDir\n";
echo "模式: " . ($dryRun ? '乾運行(僅檢測)' : '實際修改') . ($backup ? ' | 備份原文件' : '') . "\n";
echo str_repeat('-', 60) . "\n";

$found = 0;
$removed = 0;
$errors = 0;

$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($baseDir, RecursiveDirectoryIterator::SKIP_DOTS),
    RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($iterator as $file) {
    if (!$file->isFile()) continue;
    // 可選:只處理特定副檔名
    $ext = strtolower($file->getExtension());
    if (!in_array($ext, ['php', 'html', 'htm', 'css', 'js', 'json', 'xml', 'txt', 'ini', 'yml', 'yaml'])) {
        continue;
    }

    $path = $file->getPathname();
    $content = @file_get_contents($path);
    if ($content === false) {
        echo "[讀取失敗] $path\n";
        $errors++;
        continue;
    }

    if (hasBom($content)) {
        $found++;
        $relPath = str_replace($baseDir . DIRECTORY_SEPARATOR, '', $path);
        echo "[發現 BOM] $relPath\n";
        
        if (!$dryRun) {
            if ($backup) {
                $bak = $path . '.bom_bak_' . date('YmdHis');
                if (!@copy($path, $bak)) {
                    echo "  → 備份失敗,跳過修改\n";
                    $errors++;
                    continue;
                }
            }
            $newContent = removeBom($content);
            if (@file_put_contents($path, $newContent, LOCK_EX) !== false) {
                echo "  → 已移除 BOM\n";
                $removed++;
            } else {
                echo "  → 寫入失敗(權限不足?)\n";
                $errors++;
            }
        }
    }
}

echo str_repeat('-', 60) . "\n";
echo "掃描完成。檢測到 BOM 文件: $found, 已移除: $removed, 錯誤: $errors\n";

if ($dryRun && $found > 0) {
    echo "提示: 加上 --dry-run 0 或不帶 --dry-run 參數可執行實際移除。\n";
}

使用示例

# 1. 僅檢測當前目錄
php del_bom.php

# 2. 檢測指定目錄並顯示彩色輸出(CLI)
php del_bom.php /var/www/html --dry-run

# 3. 實際移除並備份原文件
php del_bom.php /var/www/html --backup

# 4. Web 方式(將腳本放入項目目錄訪問)
# https://example.com/del_bom.php?dir=.&dry=1
# https://example.com/del_bom.php?dir=application&backup=1

編輯器層面預防 BOM

編輯器/IDE設置無 BOM 保存
VS Code右下角編碼點擊 → 「Save with Encoding」→ 選「UTF-8」(非 UTF-8 with BOM)
PhpStormFile → File Encoding → 去掉「Add BOM for UTF-8 files」
Sublime TextFile → Save with Encoding → UTF-8
Notepad++Encoding → Convert to UTF-8 (無 BOM)
Vim:set nobomb 寫入 .vimrc

CI/CD 整合建議

在佈建腳本或 Git Hook 中加入檢查:

# .git/hooks/pre-commit
#!/bin/bash
php /path/to/del_bom.php "$(git rev-parse --show-toplevel)" --dry-run
if [ $? -ne 0 ]; then
    echo "發現 BOM 文件,請先清理再提交"
    exit 1
fi

總結

BOM 是 UTF-8 文件在 Windows 記事本等工具保存時誤加入的標記,PHP 不會自動忽略。定期掃描清理、統一編輯器設置、CI 攔截,三管齊下才能杜絕「莫名空白/headers already sent」此類鬼異 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved