Получить ID родительского товара по SKU (торговое предложение)
Быстрое получение ID родительского товара через CCatalogSku с кешированием результата для оптимизации.
Как использовать
- Подключите модуль catalog, используйте SkuTable::getList с filter ID и select PRODUCT_ID или CCatalogSku::GetProductInfo.
- Для снижения нагрузки кешируйте результат (Bitrix cache по cacheId = parent_product_{skuId}, директория /catalog/parent_product/).
- Передавайте ID торгового предложения (SKU); возвращается ID родительского товара или false.
В каталоге 1С-Битрикс у торгового предложения (SKU) есть связь с родительским товаром. Для ссылок на карточку товара, хлебных крошек, фильтров и API нужен ID родительского товара по ID предложения. Проблема: при каждом запросе ходить в БД за одной связью — лишняя нагрузка; в циклах по десяткам SKU получаются десятки запросов. Симптомы: медленные списки, дублирование запросов в логах. Ниже — получение ID родительского товара через D7 (SkuTable) с кешированием на час; проверка и когда использовать классический API.
Решение
Получение ID родительского товара по торговому предложению (SKU) через CCatalogSku с кешированием. Используйте когда нужно получить базовый товар из SKU без лишних запросов к БД.
use Bitrix\Main\Application;
use Bitrix\Main\Loader;
use Bitrix\Catalog\SkuTable;
/**
* Получить ID родительского товара по SKU с кешем
* @param int $skuId ID торгового предложения
* @return int|false ID родительского товара или false
*/
function getParentProductIdBySku($skuId) {
if (!Loader::includeModule('catalog')) {
return false;
}
$cache = Application::getInstance()->getCache();
$cacheId = 'parent_product_' . $skuId;
$cacheDir = '/catalog/parent_product/';
$cacheTtl = 3600; // 1 час
if ($cache->initCache($cacheTtl, $cacheId, $cacheDir)) {
$parentId = $cache->getVars();
} elseif ($cache->startDataCache()) {
$sku = SkuTable::getList([
'filter' => ['=ID' => $skuId],
'select' => ['PRODUCT_ID'],
'limit' => 1
])->fetch();
$parentId = $sku && $sku['PRODUCT_ID'] ? (int)$sku['PRODUCT_ID'] : false;
$cache->endDataCache($parentId);
} else {
$parentId = false;
}
return $parentId;
}
Пример использования:
$skuId = 12345;
$parentId = getParentProductIdBySku($skuId);
if ($parentId) {
$product = CIBlockElement::GetByID($parentId)->GetNext();
// ссылка на карточку, хлебные крошки и т.д.
}
Используется SkuTable (D7) с полем PRODUCT_ID. Для старых версий Bitrix можно CCatalogSku::GetProductInfo($skuId); D7 предпочтительнее. Модуль catalog должен быть подключён.
Проверка
-
SKU с известным родителем — в админке найдите торговое предложение и его родительский товар (ID). Вызовите getParentProductIdBySku(skuId); должен вернуться ID родительского элемента.
-
Обычный товар (не SKU) — передайте ID элемента, который не является торговым предложением. Ожидаем false (в SkuTable записи по такому ID не будет).
-
Кеш — дважды вызовите функцию с одним и тем же skuId; второй вызов не должен выполнять запрос к БД (проверьте по логам запросов или отключите кеш и сравните время). Очистка кеша: удаление директории кеша или сброс по тегу.
-
Несуществующий skuId — передайте несуществующий ID; функция должна вернуть false.
Типичные ошибки
- Не подключён модуль catalog — без Loader::includeModule(‘catalog’) SkuTable или GetProductInfo недоступны. Проверяйте возврат includeModule и при false возвращайте false из функции.
- Кеш не инвалидируется при смене привязки — если связь SKU → товар в админке меняют редко, TTL 3600 достаточно; при частых изменениях уменьшите Ttl или сбрасывайте кеш по тегу при сохранении товара/SKU.
- Перепутаны ID товара и SKU — в каталоге с торговыми предложениями элемент списка/корзины часто является SKU; родительский товар — другой элемент. Передавайте в функцию именно ID торгового предложения.
Где применять
- Prod / dev: списки товаров, корзина, детальная страница SKU (ссылка на родителя, хлебные крошки), фильтры и API каталога, минификация запросов в циклах по SKU.
- Когда не кешировать: если связь SKU↔товар меняется в рамках одного запроса или скрипта, можно вызывать SkuTable::getList без кеша.
Связанные сниппеты: Родительский товар по ID SKU (GetProductInfo), Список цен товара, Минимальная цена по типам цен.