PHP
#bitrix#catalog#sku#php#ccatalogSku#product

Найти родительский товар по ID торгового предложения

Получение ID родительского товара через CCatalogSku::GetProductInfo с проверкой подключения модуля catalog и обработкой результата.

Как использовать

  1. Подключите модуль catalog, вызовите CCatalogSku::GetProductInfo($skuId); при успехе вернётся массив с ID и IBLOCK_ID родительского товара.
  2. Для полных данных элемента используйте getParentProductFullInfo: она возвращает поля и свойства родительского элемента инфоблока.
  3. Передавайте ID именно торгового предложения (SKU); для обычного товара GetProductInfo вернёт false.

В каталоге Bitrix по ID торгового предложения (SKU) нужно получить родительский товар: его ID и инфоблок — для ссылок, хлебных крошек и доступа к полям базового товара. Классический метод — CCatalogSku::GetProductInfo($skuId): возвращает массив с ID и IBLOCK_ID родителя или false, если переданный элемент не SKU. Проблема: без проверки результата код падает или строит неверные ссылки; иногда нужны не только ID, но и поля/свойства родителя. Симптомы: «undefined index», неверная ссылка на товар, лишние запросы к GetByID в цикле. Ниже — две функции: получение только ID и инфоблока и получение полной информации о родителе (поля + свойства); проверка и типичные ошибки.

Решение

Получение ID родительского товара по торговому предложению (SKU) через классический API. Используйте в компонентах каталога, корзины, детальных страницах товаров.

use Bitrix\Main\Loader;

/**
 * Получить ID родительского товара по SKU
 * @param int $skuId ID торгового предложения
 * @return array|false ['PRODUCT_ID' => int, 'IBLOCK_ID' => int] или false
 */
function getParentProductBySku($skuId) {
    if (!Loader::includeModule('catalog')) {
        return false;
    }
    
    $arSku = CCatalogSku::GetProductInfo($skuId);
    
    if ($arSku && isset($arSku['ID'])) {
        return [
            'PRODUCT_ID' => (int)$arSku['ID'],
            'IBLOCK_ID' => (int)$arSku['IBLOCK_ID']
        ];
    }
    
    return false;
}

/**
 * Получить полную информацию о родительском товаре
 * @param int $skuId ID торгового предложения
 * @return array|false ['FIELDS' => [], 'PROPERTIES' => [], 'IBLOCK_ID' => int] или false
 */
function getParentProductFullInfo($skuId) {
    if (!Loader::includeModule('catalog') || !Loader::includeModule('iblock')) {
        return false;
    }
    
    $productInfo = getParentProductBySku($skuId);
    if (!$productInfo) {
        return false;
    }
    
    $res = CIBlockElement::GetByID($productInfo['PRODUCT_ID']);
    if ($element = $res->GetNextElement()) {
        return [
            'FIELDS' => $element->GetFields(),
            'PROPERTIES' => $element->GetProperties(),
            'IBLOCK_ID' => $productInfo['IBLOCK_ID']
        ];
    }
    
    return false;
}

Пример использования:

$skuId = 12345;
$parentInfo = getParentProductBySku($skuId);

if ($parentInfo) {
    echo 'Родительский товар ID: ' . $parentInfo['PRODUCT_ID'];
    echo 'Инфоблок ID: ' . $parentInfo['IBLOCK_ID'];
}

$fullInfo = getParentProductFullInfo($skuId);
if ($fullInfo) {
    echo $fullInfo['FIELDS']['NAME'];
}

GetProductInfo возвращает данные только если переданный ID — торговое предложение. Для обычного товара вернётся false. В новых версиях Bitrix можно использовать D7: SkuTable или родитель по SKU с кешем.

Проверка

  1. Известный SKU — возьмите ID торгового предложения из карточки в админке, вызовите getParentProductBySku($skuId). Ожидаем массив с PRODUCT_ID и IBLOCK_ID; PRODUCT_ID должен совпадать с ID родительского товара в каталоге.

  2. Обычный товар — передайте ID элемента, который не является SKU (нет записи в привязке каталога). Ожидаем false.

  3. Полная информация — getParentProductFullInfo($skuId) должна вернуть FIELDS (NAME, CODE и т.д.) и PROPERTIES родительского элемента. Проверьте, что NAME совпадает с названием товара в админке.

  4. Несуществующий ID — GetProductInfo для несуществующего ID вернёт false; обрабатывайте это в шаблоне (не строить ссылку на родителя).

Типичные ошибки

  • Обращение к ключам без проверки — всегда проверяйте возврат getParentProductBySku перед использованием PRODUCT_ID и IBLOCK_ID, иначе при переданном обычном товаре или несуществующем ID будет ошибка.
  • Передан ID товара вместо SKU — в списке могут быть и товары без торговых предложений, и SKU. У SKU в каталоге есть привязка к родителю; у обычного товара GetProductInfo вернёт false. Определяйте тип элемента (например по наличию привязки в каталоге) и передавайте в функцию только ID SKU.
  • Модуль iblock не подключён для FullInfo — getParentProductFullInfo использует CIBlockElement::GetByID; без Loader::includeModule(‘iblock’) будет ошибка. Подключайте оба модуля: catalog и iblock.

Где применять

  • Prod / dev: карточка SKU (ссылка на родителя, хлебные крошки), корзина, списки, когда нужны ID и инфоблок родителя или его поля и свойства. Классический API подходит при отсутствии D7 или когда кеш не нужен.
  • С кешем: при частых вызовах в циклах используйте вариант с кешированием по SKU.

Связанные сниппеты: Родительский товар по SKU с кешем (D7), Список цен товара, Минимальная цена по типам цен.