PHP 8.5: Все константы MHASH_* объявлены устаревшими

В PHP 8.5 все константы MHASH_* объявлены устаревшими. Узнайте, почему это важно для безопасности и совместимости вашего кода, и как подготовиться к переходу на современное API hash.

Расширение 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. Проверка результатов

После автоматической замены:

  1. Запустите тесты, особенно те, что касаются хеширования и HMAC
  2. Проверьте работу криптографических функций
  3. Убедитесь, что hash() с параметром $binary = true возвращает те же данные, что и mhash()
  4. Для HMAC проверьте, что hash_hmac() даёт ожидаемый результат (помните о различии алгоритмов!)

Влияние на обратную совместимость

PHP-приложения, использующие функции mhash с константами MHASH_*, теперь получают дополнительное уведомление об устаревании для каждого использования константы MHASH_*.

Следуйте рекомендуемой замене с помощью функции hash для исправления, совместимого с разными версиями.

Таким образом, уровень обратной совместимости, о котором говорилось в начале, теперь помечен как устаревший. Важно понимать, что объявление устаревания — это предупреждение о том, что функция или константа может быть удалена в будущих мажорных версиях PHP. Хотя код продолжит работать в PHP 8.5, рекомендуется провести миграцию как можно скорее, чтобы избежать сбоев при обновлении до PHP 9.0 или более поздних версий, где эти элементы, вероятно, будут удалены полностью.

Комментарии


Дополнительные материалы

Предыдущая Статья

PHP 8.5: Вывод из обработчиков буфера вывода объявлен устаревшим

Следующая Статья

PHP 8.5: CLI/CGI: Удалён параметр `-z` / `--zend-extension`