В интернет-магазинах на Битрикс часто используютсяторговые предложения (SKU)— вариации одного товара (например, разные размеры или цвета). Иногда возникает задача:зная ID предложения, получить ID основного товара.
Это может понадобиться для:
-
Быстрого просмотра товара (quick view)
-
Корзины, где нужно отображать основной товар вместо SKU
-
Экспорта данных в CRM или маркетплейсы
-
Фильтрации и аналитики
Рассмотрим3 рабочих способарешения этой задачи.
1. Классический метод:CCatalogSku::GetProductInfo()
Самый простой и надежный способ — использовать встроенный API Битрикс.
Код:
<?php
// Подключаем модуль catalog
if (CModule::IncludeModule("catalog")) {
$offerId = 100; // ID торгового предложения
$productInfo = CCatalogSku::GetProductInfo($offerId);
if (is_array($productInfo)) {
$parentProductId = $productInfo['ID']; // ID родительского товара
} else {
// Если это не предложение, вернём исходный ID
$parentProductId = $offerId;
}
echo "ID основного товара: " . $parentProductId;
}
?>Плюсы:
Официальный метод Битрикс
Минимальный код
Работает в любых версиях (D7 и старых)
Минусы:
Нет встроенного кэширования
2. Современный способ: D7 (Bitrix\Catalog\ProductTable)
Если проект используетD7 (API нового поколения), лучше применять этот вариант.
Код:
<?php
use Bitrix\Catalog\ProductTable;
if (Bitrix\Main\Loader::includeModule('catalog')) {
$offerId = 100;
$product = ProductTable::getList([
'filter' => ['ID' => $offerId],
'select' => ['ID', 'IBLOCK_ELEMENT_SUFFIX']
])->fetch();
$parentProductId = $product['IBLOCK_ELEMENT_SUFFIX'] ?? $offerId;
echo "ID основного товара: " . $parentProductId;
}
?>Плюсы:
Современный API (рекомендуется для новых проектов)
Лучшая производительность
Поддержка ORM
Минусы:
Работает только в D7
Сложнее для новичков
3. Резервный вариант: SQL-запрос (если API недоступен)
В редких случаях (например, при проблемах с API) можно использоватьпрямой SQL-запрос.
Код:
<?php
$offerId = 100;
$connection = Bitrix\Main\Application::getConnection();
$rsParent = $connection->query("
SELECT PRODUCT_ID
FROM b_catalog_product
WHERE ID = " . (int)$offerId . "
");
if ($parentData = $rsParent->fetch()) {
$parentProductId = $parentData['PRODUCT_ID'];
} else {
$parentProductId = $offerId;
}
echo "ID основного товара: " . $parentProductId;
?>Когда использовать:
Если стандартные методы не работают
Для сложных выборок (например, в миграциях)
Опасности:
Нет проверки прав доступа
Риск SQL-инъекций (используйте(int)илиprepare)
Дополнительные улучшения
1. Кэширование результата
Если метод вызывается часто, лучшекэшироватьрезультат.
$cache = Bitrix\Main\Data\Cache::createInstance();
$cacheKey = 'offer_parent_' . $offerId;
$cacheDir = '/catalog/';
if ($cache->initCache(3600, $cacheKey, $cacheDir)) {
$parentProductId = $cache->getVars();
} else {
$productInfo = CCatalogSku::GetProductInfo($offerId);
$parentProductId = is_array($productInfo) ? $productInfo['ID'] : $offerId;
$cache->endDataCache($parentProductId);
}2. Обработка ошибок
Добавим проверку на ошибки:
try {
if (!Bitrix\Main\Loader::includeModule('catalog')) {
throw new Exception("Модуль catalog не подключен!");
}
// ... основной код ...
} catch (Exception $e) {
echo "Ошибка: " . $e->getMessage();
}Вывод
| Метод | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
CCatalogSku::GetProductInfo
|
Универсальное решение | Простота, работает везде | Нет кэша |
D7 (ProductTable)
|
Новые проекты | Быстрее, современный API | Только D7 |
| SQL-запрос | Крайние случаи | Максимальная скорость | Риск безопасности |
Рекомендация:
-
Для стандартных задач используйте
CCatalogSku::GetProductInfo. -
В новых проектах —D7 (
ProductTable). -
SQL — только если API недоступен.
Теперь вы знаете, какнайти ID товара по ID торгового предложенияв Битрикс!