php无内置diff函数,推荐使用php-diff库处理多行文本差异,支持忽略空白、上下文行数等参数,并通过getdeltas()结构化提取增删改行。

PHP 里没有内置的 diff 函数,别直接调用
PHP 标准库不提供类似 Unix diff 命令的文本差异计算函数,xdiff 扩展虽存在但默认不启用、Windows 下编译麻烦、PHP 8+ 兼容性差。硬写 LCS(最长公共子序列)算法容易出边界错误,且性能对大文件不友好。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 小文本(symfony/console 的
DiffOutputFormatter+ArrayDiff类(需引入symfony/console或symfony/finder) - 中等文本(10KB–1MB):调用系统
diff命令(Linux/macOS)或fc(Windows),注意转义路径和编码 - 必须纯 PHP、无扩展、跨平台:用
php-diff库(sebastian/diff已弃用,推荐php-diff/php-diff)
用 exec('diff') 时中文乱码和换行丢失怎么修
直接 exec("diff file1.txt file2.txt") 在中文环境常返回空或乱码,本质是 shell 编码与 PHP 文件编码不一致,且 diff 默认输出不含颜色和换行控制符,PHP 接收时可能截断。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 统一用 UTF-8:确保两个文件保存为 UTF-8 无 BOM,PHP 脚本也声明
mb_internal_encoding('UTF-8') - 强制
diff输出 UTF-8:加参数-U 0 --color=never,避免 ANSI 控制符干扰解析 - 用
proc_open替代exec,显式设置环境变量LANG=C.UTF-8(Linux/macOS)或chcp 65001 >nul(Windows) - Windows 下优先用
fc /n /u file1.txt file2.txt,/u表示 Unicode 输出,比diff更稳
php-diff/php-diff 库对比多行文本的实际写法
这个库能处理换行、空格敏感度、忽略空白行等,比手撕逻辑靠谱得多,但默认行为容易误解——它把字符串按行切分后比较,不是字符级 diff。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 安装:
composer require php-diff/php-diff - 基础用法:
$diff = new \Diff\Diff($oldText, $newText); $renderer = new \Diff\Renderer\Text\Unified(); echo $renderer->render($diff); - 关键参数:传入
['ignoreWhitespace' => true]可忽略行首尾空格;['context' => 3]控制上下文行数(默认 3) - 注意:输入必须是字符串,不能直接传文件路径;大文件先
file_get_contents(),但别超内存限制(建议 >5MB 文件走流式预处理)
对比结果怎么结构化提取增删行,而不是只看文本输出
很多人卡在“能显示 diff 结果,但没法自动判断哪几行被删、哪几行新增”,因为 Unified 格式是给人读的,不是给程序解析的。直接正则匹配 ^+/^- 极易误判(比如代码里有 + 号)。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用库自带的
$diff->getDeltas()方法,返回数组,每个元素含type(Diff::ADDED/Diff::REMOVED/Diff::CHANGED)、orig(原文本行)、final(新文本行) - 逐行处理前,先用
array_values(array_filter(explode("\n", $text)))清理空行,避免因空行位置偏移导致行号错乱 - 如果要定位到原始文件行号,得自己维护行号映射——
php-diff不返回原始行号,只返回变化块内的相对偏移











