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_CRC320crc32
MHASH_MD51md5
MHASH_SHA12sha1
MHASH_HAVAL2563haval256,3
MHASH_RIPEMD1605ripemd160
MHASH_TIGER7tiger192,3
MHASH_GOST8gost
MHASH_CRC32B9crc32b
MHASH_HAVAL22410haval224,3
MHASH_HAVAL19211haval192,3
MHASH_HAVAL16012haval160,3
MHASH_HAVAL12813haval128,3
MHASH_TIGER12814tiger128,3
MHASH_TIGER16015tiger160,3
MHASH_MD416md4
MHASH_SHA25617sha256
MHASH_ADLER3218adler32
MHASH_SHA22419sha224
MHASH_SHA51220sha512
MHASH_SHA38421sha384
MHASH_WHIRLPOOL22whirlpool
MHASH_RIPEMD12823ripemd128
MHASH_RIPEMD25624ripemd256
MHASH_RIPEMD32025ripemd320
MHASH_SNEFRU25627snefru256
MHASH_MD228md2
MHASH_FNV13229fnv132
MHASH_FNV1A3230fnv1a32
MHASH_FNV16431fnv164
MHASH_FNV1A6432fnv1a64
MHASH_JOAAT33joaat
MHASH_CRC32C34crc32c
MHASH_MURMUR3A35murmur3a
MHASH_MURMUR3C36murmur3c
MHASH_MURMUR3F37murmur3f
MHASH_XXH3238xxh32
MHASH_XXH6439xxh64
MHASH_XXH340xxh3
MHASH_XXH12841xxh128

Рекомендуемая замена

Как и в случае с функциями 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`