PHP 8.5: атрибут NoDiscard для ключа кеша (Bitrix)
Функция формирования ключа кеша с #[ oDiscard] (PHP 8.5): предупреждение, если возвращаемое значение не использовано. Приведение (void) для явного игнорирования.
Как использовать
- Добавьте #[ oDiscard] перед объявлением функции, возвращающей ключ кеша (или другой важный результат).
- Если результат вызова не используется и не отброшен явно через (void), PHP выдаст предупреждение.
- Для намеренного игнорирования вызывайте: (void) buildCacheKey(...); PHP 8.5+.
Функция формирует ключ кеша или ID, но вызывающий код иногда забывает подставить результат в get/set — кеш работает не с тем ключом или не срабатывает. Ошибка проявляется не сразу. В PHP 8.5 добавлен атрибут NoDiscard: если возвращаемое значение функции не использовано и не отброшено явно через (void), выдаётся предупреждение. Проблема: вызов buildCacheKey() без присвоения в переменную — ключ теряется, кеш по неверному ключу. Симптомы: кеш «не держит» данные, дублирование запросов. Ниже — функция ключа кеша с #[\NoDiscard], пример использования в Bitrix Cache и подавление предупреждения через (void); проверка и типичные ошибки.
Решение
Атрибут #[\NoDiscard] заставляет учитывать возвращаемое значение: не использовано и не отброшено через (void) — предупреждение. Удобно для функций, формирующих ключ кеша, ID или URL.
<?php
#[\NoDiscard]
function buildCacheKey(string $module, string $entity, string $id): string
{
return $module . ':' . $entity . ':' . $id;
}
// Предупреждение: return value should be used or (void)
buildCacheKey('sale', 'order', '123');
// Корректно: результат используется
$key = buildCacheKey('sale', 'order', '123');
$cache->get($key);
// Корректно: намеренное игнорирование
(void) buildCacheKey('sale', 'order', '123');
Использование с Bitrix Cache:
use Bitrix\Main\Data\Cache;
$cache = Cache::createInstance();
$key = buildCacheKey('sale', 'order', (string) $orderId);
if ($cache->initCache(3600, $key, '/sale/order/')) {
$data = $cache->getVars();
} elseif ($cache->startDataCache()) {
// ...
$cache->endDataCache($data);
}
По документации PHP 8.5: атрибут в глобальном пространстве — #[\NoDiscard]. Приведение (void) не меняет выполнение, но подавляет предупреждение и явно показывает намерение не использовать значение.
Проверка
- Предупреждение при неиспользовании результата — вызовите функцию без присвоения и без (void):
#[\NoDiscard]
function buildCacheKey(string $module, string $entity, string $id): string
{
return $module . ':' . $entity . ':' . $id;
}
buildCacheKey('sale', 'order', '123');
Запуск с отображением предупреждений (например php -d error_reporting=E_ALL script.php) должен выдать предупреждение о том, что возвращаемое значение должно быть использовано или отброшено через (void).
-
Использование результата — при присвоении в переменную или передаче в другой вызов предупреждения не должно быть.
-
Явное игнорирование — строка
(void) buildCacheKey(...);не должна вызывать предупреждение. Подходит для случаев, когда ключ нужен только для сброса по тегу или побочного эффекта. -
PHP 8.5 — атрибут NoDiscard появился в 8.5. На старых версиях атрибут может игнорироваться. Проверьте:
php -v.
Типичные ошибки
- Игнорирование предупреждения — если результат действительно не нужен (например только сброс кеша по тегу), явно пишите
(void) buildCacheKey(...);. Иначе при включённых предупреждениях лог засоряется или CI падает. - Функция возвращает void — #[\NoDiscard] имеет смысл только у функций, возвращающих значение. У void-функций возвращаемого значения нет, атрибут не нужен.
- Путаница с (void) — (void) не выполняет функцию заново и не меняет поведение; это только приведение типа результата для подавления предупреждения NoDiscard.
Где применять
- Bitrix: ключи кеша по модулю/сущности/ID, теги, любые функции, чей результат обязан быть передан в initCache/startDataCache или другой API.
- Любой PHP 8.5+: генерация ID, URL, токенов — везде, где забытый результат ведёт к трудноотлаживаемой ошибке.
Связанные сниппеты: Option::get с union type, Идемпотентный агент с блокировкой, Cron/Agent: lock-файл.