md5_file()
Статья о функции PHP md5_file(), которая вычисляет MD5-хэш файла. Полезна для проверки целостности и дедупликации.
Функция PHP md5_file() читает файл и возвращает MD5-хэш его содержимого в виде 32-символьной шестнадцатеричной строки. В отличие от md5(), которая хэширует строку, уже находящуюся в памяти, md5_file() читает файл с диска потоково — поэтому можно получить отпечаток файла любого размера, не загружая его целиком в переменную.
На этой странице рассматриваются синтаксис, оба режима вывода, практические задачи, для которых md5_file() подходит (проверка целостности, обнаружение изменений, дедупликация), подводные камни и случаи, когда MD5 является неподходящим инструментом.
Синтаксис
md5_file(string $filename, bool $binary = false): string|false| Параметр | Описание |
|---|---|
$filename | Путь к файлу для хэширования. Может быть локальным путём или URL потокового обёртки (http://, php:// и т.д.), если обёртки включены. |
$binary | Если false (по умолчанию), возвращает 32-символьную строку в нижнем регистре. Если true, возвращает 16 сырых байт. |
Возвращаемое значение: MD5-хэш при успехе или false, если файл не удалось прочитать. (До PHP 8.0 второй аргумент назывался $raw_output.)
Базовый пример
Хэш вычисляется из байтов файла, поэтому файл, содержащий ровно текст Hello, World! (без завершающей новой строки), всегда даёт одинаковый дайджест:
Вывод:
65a8e27d8879283831b664bd8b7f0ad4Поскольку MD5 детерминирован, хэширование одного и того же содержимого в любом месте — на любой машине, на любом языке — даёт это же значение. Именно это свойство делает его полезным в описанных ниже случаях.
Проверка целостности файла
Наиболее распространённое применение — подтверждение того, что загруженный файл соответствует опубликованной контрольной сумме. Сравнивайте вычисленный хэш с ожидаемым значением с помощью hash_equals() (сравнение, защищённое от атак по времени), а не оператора ==:
<?php
$expected = "65a8e27d8879283831b664bd8b7f0ad4";
$actual = md5_file("example.txt");
if ($actual === false) {
echo "Could not read the file.";
} elseif (hash_equals($expected, $actual)) {
echo "File is intact.";
} else {
echo "File is corrupted or has been modified.";
}
?>Обнаружение изменений и дедупликация
Хранение хэша файла позволяет дёшево определить, изменился ли он впоследствии: достаточно снова вычислить хэш и сравнить с сохранённым значением. Два файла с одинаковым хэшем (с подавляющей вероятностью) идентичны побайтово, что делает md5_file() удобным инструментом для поиска дубликатов:
<?php
$a = md5_file("photo1.jpg");
$b = md5_file("photo2.jpg");
echo ($a === $b) ? "Duplicate files\n" : "Different files\n";
?>Вывод в виде сырых байт
Передайте true вторым аргументом, чтобы получить 16 сырых байт вместо 32 шестнадцатеричных символов. Это полезно, когда нужно компактно хранить хэш в столбце базы данных с фиксированной шириной BINARY(16):
<?php
$raw = md5_file("example.txt", true);
echo strlen($raw); // 16 (bytes) instead of 32 (hex chars)
echo bin2hex($raw); // 65a8e27d8879283831b664bd8b7f0ad4
?>Обработка ошибок
Если путь отсутствует или файл недоступен для чтения, md5_file() возвращает false и генерирует предупреждение. Всегда проверяйте наличие файла перед хэшированием, чтобы иметь возможность вывести понятное сообщение об ошибке:
<?php
$filename = "example.txt";
if (!is_readable($filename)) {
echo "File not found or not readable.";
} else {
echo md5_file($filename);
}
?>Когда не следует использовать MD5
MD5 быстр и подходит для несекьюрных задач, таких как обнаружение изменений, ключи кэширования и дедупликация. Для задач безопасности он скомпрометирован: злоумышленники могут создать два разных файла с одинаковым MD5-хэшем (коллизия). Не используйте его для:
- хранения паролей (используйте
password_hash()), - защиты от злонамеренного изменения файла.
Для устойчивых к подделке отпечатков предпочтительнее использовать дайджест семейства SHA-2 через hash_file():
<?php
echo hash_file("sha256", "example.txt");
?>Связанные функции
md5()— хэширует строку вместо файла.sha1_file()— SHA-1 хэш содержимого файла.crc32()— быстрая 32-битная контрольная сумма для обнаружения ошибок.file_get_contents()— читает весь файл в строку.
Итоги
md5_file() возвращает MD5-дайджест содержимого файла — по умолчанию в виде шестнадцатеричной строки или сырых байт при $binary = true. Она идеально подходит для проверки целостности, обнаружения изменений и дедупликации, но никогда не должна применяться для задач безопасности, где правильным выбором является SHA-2 хэш через hash_file().