PHP 8.5: Все константы MHASH_* объявлены устаревшими
Расширение Hash, входящее в ядро PHP, для поддержки старого кода включает уровень обратной совместимости для класса функций mhash, которые расширение hash заменило. Начиная с PHP 8.1, отдельное расширение mhash удалено из ядра PHP, и все его функции эмулируются расширением Hash. Это означает, что константы MHASH_* и связанные с ними функции остаются доступными, но при их использовании генерируются уведомления об устаревании.
В PHP 8.1 все функции mhash были объявлены устаревшими. Сюда входили функции mhash, mhash_count, mhash_get_block_size, mhash_get_hash_name и mhash_keygen_s2k.
Однако в PHP 8.1 константы PHP, которые эти функции принимали в качестве параметров, не были объявлены устаревшими. В PHP 8.5 все константы MHASH_* объявлены устаревшими наряду с существующим объявлением устаревания функций mhash.
Следующий фрагмент кода выдаёт сообщение об устаревании функции mhash в PHP 8.1 и более поздних версиях:
mhash(MHASH_SHA1, 'test');
// Function mhash() is deprecated since 8.1 ...
В PHP 8.5 и более поздних версиях, поскольку константы MHASH_* также объявлены устаревшими, при выполнении такого кода вы можете получить дополнительное уведомление об устаревании самой константы:
mhash(MHASH_SHA1, 'test');
// Constant MHASH_SHA1 is deprecated ....
// Function mhash() is deprecated since 8.1 ...
Для перехода на современный API необходимо заменить использование констант MHASH_* на их строковые эквиваленты, которые принимает функция hash. В таблице ниже приведён полный список соответствий.
Константа mhash |
Значение константы | Значение string для hash() |
|---|---|---|
MHASH_CRC32 |
0 | crc32 |
MHASH_MD5 |
1 | md5 |
MHASH_SHA1 |
2 | sha1 |
MHASH_HAVAL256 |
3 | haval256,3 |
MHASH_RIPEMD160 |
5 | ripemd160 |
MHASH_TIGER |
7 | tiger192,3 |
MHASH_GOST |
8 | gost |
MHASH_CRC32B |
9 | crc32b |
MHASH_HAVAL224 |
10 | haval224,3 |
MHASH_HAVAL192 |
11 | haval192,3 |
MHASH_HAVAL160 |
12 | haval160,3 |
MHASH_HAVAL128 |
13 | haval128,3 |
MHASH_TIGER128 |
14 | tiger128,3 |
MHASH_TIGER160 |
15 | tiger160,3 |
MHASH_MD4 |
16 | md4 |
MHASH_SHA256 |
17 | sha256 |
MHASH_ADLER32 |
18 | adler32 |
MHASH_SHA224 |
19 | sha224 |
MHASH_SHA512 |
20 | sha512 |
MHASH_SHA384 |
21 | sha384 |
MHASH_WHIRLPOOL |
22 | whirlpool |
MHASH_RIPEMD128 |
23 | ripemd128 |
MHASH_RIPEMD256 |
24 | ripemd256 |
MHASH_RIPEMD320 |
25 | ripemd320 |
MHASH_SNEFRU256 |
27 | snefru256 |
MHASH_MD2 |
28 | md2 |
MHASH_FNV132 |
29 | fnv132 |
MHASH_FNV1A32 |
30 | fnv1a32 |
MHASH_FNV164 |
31 | fnv164 |
MHASH_FNV1A64 |
32 | fnv1a64 |
MHASH_JOAAT |
33 | joaat |
MHASH_CRC32C |
34 | crc32c |
MHASH_MURMUR3A |
35 | murmur3a |
MHASH_MURMUR3C |
36 | murmur3c |
MHASH_MURMUR3F |
37 | murmur3f |
MHASH_XXH32 |
38 | xxh32 |
MHASH_XXH64 |
39 | xxh64 |
MHASH_XXH3 |
40 | xxh3 |
MHASH_XXH128 |
41 | xxh128 |
Рекомендуемая замена
Как и в случае с функциями mhash, рекомендуемая замена для предотвращения появления уведомления об устаревании заключается в переходе с функций и констант mhash на соответствующие функции семейства hash.
-$hash = mhash(MHASH_SHA1, 'test');
+$hash = hash('sha1', 'test', true);
Функция hash принимает строковое значение для имени алгоритма (sha1 в примере), в отличие от константы в mhash. По умолчанию hash() возвращает хеш в виде шестнадцатеричной строки. Чтобы получить бинарные данные (raw binary output) — что соответствует возвращаемому значению оригинальной функции mhash() — необходимо установить третий параметр ($binary) в true.
Вычисление HMAC
Стоит отметить, что для генерации HMAC в устаревшем расширении mhash использовалась отдельная функция mhash_keygen_s2k. В современном расширении Hash для этой задачи следует использовать специализированную функцию hash_hmac.
-$hmac = mhash_keygen_s2k(MHASH_SHA1, 'test', 'secret-key');
+$hmac = hash_hmac('sha1', 'test', 'secret-key', true);
Автоматизация замены устаревшего кода
Хотя замена отдельных вызовов проста, в большом проекте ручная правка всех файлов может быть трудоёмкой. Для автоматизации этого процесса рекомендуется использовать специализированные инструменты:
1. Поиск устаревшего кода
PHPStan — статический анализатор, который может обнаруживать использование устаревших функций и констант. Настройте в phpstan.neon:
parameters:
level: max
checkDeprecated: true # Включает проверку устаревших элементов
После настройки PHPStan будет явно указывать на каждое использование MHASH_* констант.
Простой поиск через grep:
# Найти все использования констант MHASH_*
grep -r "MHASH_[A-Z0-9_]*" src/ tests/
# Найти вызовы функций mhash
grep -r "mhash\([^)]*\)" src/
2. Автоматическая замена
Для автоматической замены рекомендуется использовать:
Rector — инструмент для автоматического рефакторинга. Хотя готового правила для MHASH_* нет в стандартном наборе, его можно создать самостоятельно. Пример простого кастомного правила:
use PhpParser\Node;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Scalar\String_;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
class MhashConstantToHashStringRector extends AbstractRector
{
private const MHASH_MAP = [
'MHASH_SHA1' => "'sha1'",
'MHASH_MD5' => "'md5'",
// Добавьте остальные константы из таблицы выше
];
public function getNodeTypes(): array
{
return [ConstFetch::class];
}
public function refactor(Node $node): ?Node
{
if (!$node instanceof ConstFetch) {
return null;
}
$constantName = $this->getName($node);
if ($constantName && array_key_exists($constantName, self::MHASH_MAP)) {
// Заменяем константу на строковое значение
return new String_(trim(self::MHASH_MAP[$constantName], "'"));
}
return null;
}
}
PHPCBF (PHP Code Beautifier and Fixer) — инструмент из набора PHP_CodeSniffer, который может автоматически исправлять код по заданным правилам.
3. Проверка результатов
После автоматической замены:
- Запустите тесты, особенно те, что касаются хеширования и HMAC
- Проверьте работу криптографических функций
- Убедитесь, что
hash()с параметром$binary = trueвозвращает те же данные, что иmhash() - Для HMAC проверьте, что
hash_hmac()даёт ожидаемый результат (помните о различии алгоритмов!)
Влияние на обратную совместимость
PHP-приложения, использующие функции mhash с константами MHASH_*, теперь получают дополнительное уведомление об устаревании для каждого использования константы MHASH_*.
Следуйте рекомендуемой замене с помощью функции hash для исправления, совместимого с разными версиями.
Таким образом, уровень обратной совместимости, о котором говорилось в начале, теперь помечен как устаревший. Важно понимать, что объявление устаревания — это предупреждение о том, что функция или константа может быть удалена в будущих мажорных версиях PHP. Хотя код продолжит работать в PHP 8.5, рекомендуется провести миграцию как можно скорее, чтобы избежать сбоев при обновлении до PHP 9.0 или более поздних версий, где эти элементы, вероятно, будут удалены полностью.