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 или более поздних версий, где эти элементы, вероятно, будут удалены полностью.