Рано или поздно для интернет-магазинов возникает необходимость вывода товаров на Яндекс.Маркет. Это мощный канал привлечения клиентов: по статистике Яндекса, миллионы покупателей по всей России выбирают этот сервис, чтобы сравнить цены и найти лучшее предложение.
Для передачи данных о товарах Яндекс.Маркет требует загрузить прайс-лист в особом формате — YML (Yandex Market Language), который является разновидностью XML. Такой файл можно генерировать динамически с помощью PHP. В этой статье я подробно расскажу, как создать его для магазина на движке osCommerce.
- Как это работает: от регистрации до выгрузки
- Создание YML-файла: Пошаговый разбор кода
- Шаг 1: Заголовок и подключение к базе данных
- Шаг 2: Формирование «шапки» YML-файла
- Шаг 3: Выгрузка категорий товаров
- Шаг 4: Выгрузка товарных предложений (offers)
- Шаг 5: Завершение XML и вывод результата
- Пример итогового YML-файла (сокращенная версия)
- Важные примечания и рекомендации
Как это работает: от регистрации до выгрузки
После регистрации магазина на Яндекс.Маркете вам необходимо будет указать ссылку на ваш прайс-лист. По этой ссылке должен располагаться скрипт (в нашем случае — ya-market.php), который при каждом обращении со стороны Яндекса будет динамически формировать актуальный YML-файл, обращаясь к базе данных вашего магазина.
Почему я написала свой скрипт? В интернете я нашла несколько готовых решений для osCommerce, но в моем случае они оказались непригодными — либо устаревшими, либо содержащими ошибки. Поэтому я полностью переписала один из найденных PHP-файлов, исправив логику, код и адаптировав его под современные требования. Ниже представлен итоговый рабочий код с подробными комментариями.
Создание YML-файла: Пошаговый разбор кода
Шаг 1: Заголовок и подключение к базе данных
Первым делом скрипт должен сообщить, что он выдает XML, и подключиться к базе данных MySQL, где хранятся все данные osCommerce.
<?php
// Устанавливаем заголовок для вывода XML
header("Content-Type: application/xml; charset=utf-8");
// Параметры подключения к БД. ЗАМЕНИТЕ ИХ НА СВОИ!
$db_host = 'localhost'; // Адрес сервера БД
$db_user = 'username'; // Имя пользователя БД
$db_pass = 'password'; // Пароль пользователя БД
$db_name = 'database_name'; // Имя базы данных магазина
// Устанавливаем соединение
$dbc = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
if (!$dbc) {
die('Ошибка подключения: ' . mysqli_connect_error());
}
// Важно: Устанавливаем корректную кодировку соединения.
// Если ваша БД использует кодировку latin1, укажите её.
// Для современных магазинов рекомендуется utf8.
mysqli_set_charset($dbc, 'latin1');
?> Шаг 2: Формирование «шапки» YML-файла
Начинаем генерировать XML, добавляя обязательные элементы: информацию о магазине, валютах и времени создания файла.
<?php
// Данные вашего магазина для заголовка YML
$cdate = date("Y-m-d H:i"); // Текущая дата и время
$csite = "http://www.moy-sayt.ru/"; // Вписать адрес интернет-магазина
$cname = "Название вашего магазина"; // Вписать название интернет-магазина
$cdesc = "Подробное описание вашего интернет-магазина"; // Вписать описание
// Начинаем формировать XML-структуру
$yandex = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$yandex .= '<!DOCTYPE yml_catalog SYSTEM "shops.dtd">' . "\n";
$yandex .= '<yml_catalog date="' . $cdate . '">' . "\n";
$yandex .= ' <shop>' . "\n";
$yandex .= ' <name>' . htmlspecialchars($cname) . '</name>' . "\n";
$yandex .= ' <company>' . htmlspecialchars($cname) . '</company>' . "\n";
$yandex .= ' <url>' . $csite . '</url>' . "\n";
$yandex .= ' <platform>osCommerce</platform>' . "\n";
$yandex .= ' <currencies>' . "\n";
$yandex .= ' <currency id="RUR" rate="1"/>' . "\n"; // Основная валюта - российский рубль
$yandex .= ' </currencies>' . "\n";
?> Шаг 3: Выгрузка категорий товаров
В osCommerce данные о категориях обычно разделены между двумя таблицами. Нам нужен запрос, который объединит categories (ID и родительская категория) и categories_description (названия).
<?php
// Массив для хранения категорий (может пригодиться для дополнительной логики)
$arr_cats = array();
// Открываем блок <categories>
$yandex .= ' <categories>' . "\n";
// Запрос для получения всех категорий и подкатегорий
$tmp = "SELECT c.categories_id as categoryID,
cd.categories_name as name,
c.parent_id as parent
FROM categories as c,
categories_description as cd
WHERE c.categories_id = cd.categories_id
AND cd.language_id = 2
ORDER BY parent, name";
$res = mysqli_query($dbc, $tmp);
while ($row = mysqli_fetch_assoc($res)) {
// Экранируем специальные XML-символы в названии категории
$category_name = htmlspecialchars($row['name']);
// Формируем XML-тег категории
$category_xml = ' <category id="' . $row['categoryID'] . '"';
// Если у категории есть родитель, добавляем атрибут parentId
if ($row['parent'] > 0) {
$category_xml .= ' parentId="' . $row['parent'] . '"';
}
$category_xml .= '>' . $category_name . '</category>' . "\n";
// Добавляем сформированную строку в общий XML
$yandex .= $category_xml;
// Сохраняем категорию в массив (опционально, для возможного дальнейшего использования)
$arr_cats[$row['categoryID']] = $row;
}
// Закрываем блок <categories>
$yandex .= ' </categories>' . "\n";
?> Что получится в итоге (пример вывода категорий):
<categories>
<category id="1">ДИСКИ</category>
<category id="2">ШИНЫ</category>
<category id="10" parentId="1">Диски AUDI</category>
<category id="11" parentId="1">Диски BENTLEY</category>
<category id="12" parentId="1">Диски BMW</category>
<category id="13" parentId="1">Диски CADILLAC</category>
<category id="14" parentId="1">Диски CHEVROLET</category>
<category id="15" parentId="1">Диски HUMMER</category>
<category id="16" parentId="1">Диски INFINITY</category>
<category id="17" parentId="1">Диски LAND ROVER</category>
<category id="18" parentId="1">Диски LEXUS</category>
<category id="19" parentId="1">Диски MERCEDES</category>
<category id="20" parentId="1">Диски NISSAN</category>
<category id="21" parentId="1">Диски PORSCHE</category>
<category id="22" parentId="1">Диски SUBARU</category>
<category id="23" parentId="1">Диски TOYOTA</category>
<category id="24" parentId="1">Диски VOLKSWAGEN</category>
<category id="25" parentId="1">Диски VOLVO</category>
<category id="30" parentId="2">Б/У покрышки</category>
<category id="31" parentId="2">Шины. Зима</category>
<category id="32" parentId="2">Шины. Лето</category>
</categories> Шаг 4: Выгрузка товарных предложений (offers)
Это самая важная часть — вывод непосредственно товаров. Мы выбираем товары, которые активны, имеют цену и привязаны к категориям.
<?php
// Открываем блок <offers>
$yandex .= ' <offers>' . "\n";
// Запрос для получения товаров
$tmp = "SELECT p.products_id AS productID,
p.products_price AS Price,
p.products_image AS picture,
p.products_status AS in_stock,
pd.products_name AS name,
pd.products_description AS brief_description,
pc.categories_id AS categoryID
FROM products AS p,
products_description AS pd,
products_to_categories AS pc
WHERE p.products_price > 0
AND pd.products_id = p.products_id
AND pc.products_id = p.products_id
AND p.products_status = 1
AND pd.language_id = 2
ORDER BY name";
$res = mysqli_query($dbc, $tmp);
while ($tovar = mysqli_fetch_assoc($res)) {
// Подготовка данных товара
$valuta = "RUR"; // Валюта: российский рубль
$price = intval($tovar['Price']); // Цена (целое число)
// Очищаем описание от HTML-тегов и экранируем спецсимволы
$description = htmlspecialchars(strip_tags($tovar['brief_description']));
// Экранируем название товара
$product_name = htmlspecialchars($tovar['name']);
// Формируем ссылку на товар (важно: структура URL зависит от вашего магазина)
$product_url = $csite . 'catalog/' . $tovar['categoryID'] . '-p-' . $tovar['productID'] . '.html';
// Формируем ссылку на изображение товара, если оно есть
$picture_xml = '';
if (!empty($tovar['picture'])) {
$src_file = $csite . 'catalog/images/' . $tovar['picture'];
$picture_xml = ' <picture>' . htmlspecialchars($src_file) . '</picture>' . "\n";
}
// Формируем XML для одного товарного предложения
$yandex .= ' <offer id="' . $tovar['productID'] . '" available="true">' . "\n";
$yandex .= ' <url>' . $product_url . '</url>' . "\n";
$yandex .= ' <price>' . $price . '</price>' . "\n";
$yandex .= ' <currencyId>' . $valuta . '</currencyId>' . "\n";
$yandex .= ' <categoryId>' . $tovar['categoryID'] . '</categoryId>' . "\n";
if (!empty($picture_xml)) {
$yandex .= $picture_xml;
}
$yandex .= ' <name>' . $product_name . '</name>' . "\n";
$yandex .= ' <description>' . $description . '</description>' . "\n";
$yandex .= ' </offer>' . "\n\n";
}
// Закрываем блок <offers>
$yandex .= ' </offers>' . "\n";
?> Шаг 5: Завершение XML и вывод результата
<?php
// Закрываем оставшиеся теги
$yandex .= ' </shop>' . "\n";
$yandex .= '</yml_catalog>';
// Закрываем соединение с базой данных
mysqli_close($dbc);
// Выводим сгенерированный XML
echo $yandex;
?> Пример итогового YML-файла (сокращенная версия)
Вот как выглядит полный YML-файл, сгенерированный нашим скриптом (для наглядности представлены только первые несколько товаров):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2023-12-20 14:30">
<shop>
<name>Колесные диски и шины</name>
<company>Колесные диски и шины</company>
<url>http://www.moy-sayt.ru/</url>
<platform>osCommerce</platform>
<currencies>
<currency id="RUR" rate="1"/>
</currencies>
<categories>
<category id="1">ДИСКИ</category>
<category id="2">ШИНЫ</category>
<category id="10" parentId="1">Диски AUDI</category>
<category id="11" parentId="1">Диски BENTLEY</category>
<category id="12" parentId="1">Диски BMW</category>
<!-- ... остальные категории ... -->
<category id="31" parentId="2">Шины. Зима</category>
<category id="32" parentId="2">Шины. Лето</category>
</categories>
<offers>
<offer id="399" available="true">
<url>http://www.moy-sayt.ru/catalog/187-p-399.html</url>
<price>11000</price>
<currencyId>RUR</currencyId>
<categoryId>187</categoryId>
<picture>http://www.moy-sayt.ru/catalog/images/ДУИЛЕР_diski.jpg</picture>
<name>Bridgestone Dueler H/P Sport</name>
<description>265-50-19 ЦЕНА УКАЗАНА ЗА 1 КОЛЕСО Bridgestone Dueler H/P Sport- летняя шина для автомобилей 4x4 предназначена для езды на высоких скоростях по трассам и шоссе и входит в первичные комплектации автомобилей Audi Q7, Porsche Cayanne, VW Touareg, обновленной BMW X5 и т.д. Dueler H/P Sport - это великолепная управляемость как на мокрой, так и на сухой дороге. Если Вы хотите приблизить характер Вашего внедорожника к легковому автомобилю и любите динамичную езду, то Вы обязательно оцените шины Dueler H/P Sport, особенно учитывая комфорт и бесшумность, которые они обеспечивают.</description>
</offer>
<offer id="402" available="true">
<url>http://www.moy-sayt.ru/catalog/187-p-402.html</url>
<price>17500</price>
<currencyId>RUR</currencyId>
<categoryId>187</categoryId>
<picture>http://www.moy-sayt.ru/catalog/images/conticrosscontactuhp_diski.jpg</picture>
<name>Continental CrossContact UHP</name>
<description>295-35-21 ЦЕНА УКАЗАНА ЗА 1 КОЛЕСО Continental имеет в своем арсенале шины, специально разработанные для супермощных 4WD автомобилей - шины ContiCrossContact UHP. Их технические характеристики, включая кратчайший тормозной путь и исключительные показатели устойчивости при поворотах на больших скоростях и прекрасная управляемость, делают их незаменимыми для таких требовательных автомобилей 4WD, как: Porsche Cayenne, BMW X5, Range Rover Sport и т. д.</description>
</offer>
<offer id="528" available="true">
<url>http://www.moy-sayt.ru/catalog/187-p-528.html</url>
<price>5250</price>
<currencyId>RUR</currencyId>
<categoryId>187</categoryId>
<picture>http://www.moy-sayt.ru/catalog/images/DEREZA_diski.jpg</picture>
<name>dUNLOP DIREZZA DZ101 215/55 R17</name>
<description>Одна из последних разработок японского завода Dunlop. Шина произведена по усовершенствованной фирменной технологии DIGI-TYRE, получившей название Digital Rolling Simulation II: ещё меньший тормозной путь; ещё большее пятно контакта и, как следствие, великолепная устойчивость на высоких скоростях; потрясающее сцепление с мокрой дорогой; ещё меньшее сопротивление качению - меньший износ и экономия топлива; ещё меньший уровень шума. Это шина, в первую очередь, ориентирована на любителей спортивного типа вождения, но, естественно, её можно рекомендовать абсолютно всем автомобилистам.</description>
</offer>
<!-- ... остальные товары ... -->
</offers>
</shop>
</yml_catalog> Важные примечания и рекомендации
- Адаптация под вашу версию osCommerce: Скрипт был написан для osCommerce с определенными модификациями. В базовой версии osCommerce 2.3 могут быть некоторые отличия:
- Структура URL товаров может отличаться (например,
product_info.php?products_id=X) - Названия полей в базе данных могут незначительно различаться
- Могут быть другие таблицы или структура хранения данных
- Безопасность и оптимизация:
- Для рабочего магазина рекомендуется добавить кэширование файла (генерировать его не при каждом запросе, а раз в несколько часов)
- Убедитесь, что ваш сервер поддерживает вызов PHP-скриптов по ссылке
- Проверьте права доступа к файлу и папкам
- Валидация YML:
- Обязательно проверьте сгенерированный файл через валидатор Яндекс.Маркета
- Обратите внимание на ограничения по размеру файла и количеству товаров
- Дополнительные поля:
- В спецификации YML есть много полезных полей, которые можно добавить:
vendor,model,param,sales_notesи др. - Рекомендую изучить официальную документацию YML для расширения функционала
- Кодировка:
- В примере используется кодировка
latin1, но для современных магазинов рекомендуетсяutf-8 - Убедитесь, что кодировка в заголовке PHP-скрипта, в базе данных и в XML-документе совпадают
Представленный скрипт полностью решает задачу выгрузки товаров из osCommerce на Яндекс.Маркет. Он охватывает все ключевые этапы: подключение к БД, формирование корректной XML-структуры, вывод категорий и товаров. Код снабжен подробными комментариями, что позволяет легко адаптировать его под особенности именно вашего магазина.
Главные преимущества этого решения:
- Полный контроль над данными и структурой выгрузки
- Возможность кастомизации и добавления дополнительных полей
- Четкое соответствие спецификации Яндекс.Маркета
- Простота понимания и модификации кода
После настройки не забудьте протестировать работу скрипта через валидатор Яндекс и добавить ссылку на него в личном кабинете Яндекс.Маркета. Удачи в продвижении вашего магазина!

