最稳妥方法是用 hash_file() 逐个计算文件哈希,因其不加载文件到内存、适合大文件;需校验算法名、路径权限、路径分隔符统一及相对路径记录,输出推荐 JSON 格式并设正确 header。

用 hash_file() 逐个计算文件哈希最稳妥
PHP 没有内置的“批量哈希”函数,所谓批量,本质是循环调用 hash_file()。它直接读取文件内容并返回哈希值,不加载进内存,适合处理大文件。别用 file_get_contents() + hash(),容易 OOM。
常见错误是传错算法名(比如写成 "sha256" 却没加引号,或误用 "sha2-256"),实际支持的必须是 hash_algos() 返回的列表里的值,如 "sha256"、"md5"、"sha1"。
- 确保文件路径存在且 PHP 有读权限,否则
hash_file()返回false,不抛异常 - 算法越长(如
"sha512")计算越慢,但碰撞概率更低;日常校验用"sha256"是平衡点 - Windows 下注意路径分隔符,建议统一用
/或DIRECTORY_SEPARATOR
遍历目录时用 scandir() 而非 glob() 更可控
glob() 看似简洁,但对隐藏文件(如 .gitignore)、符号链接、权限拒绝的条目行为不一致,还可能因通配符导致意外交叉匹配。用 scandir() + 显式过滤更可靠。
示例逻辑:先 scandir($dir) 得到所有条目,剔除 . 和 ..,再用 is_file() 和 is_readable() 双重判断,避免对目录或不可读项调用 hash_file() 报错。
立即学习“PHP免费学习笔记(深入)”;
- 递归遍历需自己写函数,
RecursiveDirectoryIterator虽强大但开销略高,简单场景没必要 - 如果目录下文件极多(上万),考虑加
set_time_limit(0)防超时 - 注意
scandir()返回结果未排序,如需顺序输出可加sort($files)
输出格式选 JSON 比纯文本更易后续处理
纯文本(如每行 filename:sha256)看着简单,但遇到含空格、冒号、换行的文件名就解析困难。JSON 天然支持转义,结构清晰,Python/JS/Shell 都能直接读取。
别手动拼 JSON 字符串,必须用 json_encode(),否则特殊字符会破坏格式。同时设 JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE 保证路径和中文可读。
- 生成前检查数组键是否合法(如文件名含
/不影响 JSON,但作为键没问题) - 若文件数量极大,一次性
json_encode()可能内存飙升,可改用流式写入(逐条fwrite()+ 手动补逗号和括号) - 不要把整个结果
echo出来就完事——加header('Content-Type: application/json; charset=utf-8')避免乱码
校验环节必须比对完整路径或相对路径一致性
哈希值本身无法定位文件,所以保存哈希时必须附带可还原的路径信息。用绝对路径最直白,但迁移后失效;用相对于扫描根目录的路径(如 docs/config.php)更灵活,前提是记录好基准目录。
常见坑是生成哈希时用 basename($file) 只存文件名,多个同名文件(如不同子目录下的 index.html)就会冲突,校验时根本分不清。
- 校验脚本运行时,应先
chdir()到原始基准目录,再按记录的相对路径拼出真实路径 - 路径分隔符统一处理:Windows 下
str_replace('\', '/', $path)再参与哈希计算,避免因斜杠方向不同导致哈希不一致 - 如果涉及跨平台共享哈希清单,务必在文档里注明路径基准和分隔符约定
/ 或编码不一致,两次哈希对不上,排查起来比重算还费时间。



















