Динамичный скрипт карты сайта Sitemap.xml на PHP для osCommerce 2.3

Default Image Лаборатория Кода

Пожалуй, написано немало статей на тему, зачем нужен файл Sitemap.xml и что с ним делают поисковики. Здесь мне не хотелось бы повторяться. Поэтому просто оговоримся, что файл Sitemap представляет собой карту сайта, содержит перечень его страниц и служит для лучшей индексации ресурса поисковыми роботами, такими как Yandex, Google и другие. На этом закончим.

Конечно, для создания карты сайта всегда можно обратиться к онлайн-генераторам Sitemap. В интернете существует много таких сервисов (найти их по запросу «sitemap generator» не составит труда). Достаточно ввести адрес сайта в предлагаемое поле, и для вас сгенерируется файл карты сайта Sitemap.xml по всем правилам. Вы сохраняете его на компьютере, переносите на сайт, а далее в Яндекс.Вебмастере просто указываете ссылку на него.

Однако такой способ имеет ряд определённых недочётов.

  1. Количество ссылок (URL-адресов вашего сайта), как правило, лимитируется генераторами в пределах от 500 до 1000. То есть для больших сайтов с количеством страниц, превышающим тысячу или даже несколько тысяч, такая карта сайта Sitemap.xml будет неполной.
  2. Если речь идёт об интернет-магазине, в котором постоянно добавляются новые товары, безусловно, единожды созданная статическая карта сайта не будет их включать. Чтобы новые товары или изменения в категориях учитывались в Sitemap.xml, необходимо создать динамичный PHP-скрипт, который будет генерировать этот файл при каждом обращении поискового робота.

Данный материал подготовлен для тех веб-разработчиков и SEO-оптимизаторов, которые стремятся продвигать сайт по всем правилам и которых уже не удовлетворяют статически сгенерированные карты сайта.

Проблема с дублирующимся контентом в автоматически созданных картах

Добавлю несколько слов о создании карты сайта Sitemap.xml посредством генераторов. Изучив такую карту для интернет-магазина на базе osCommerce, я обнаружила ещё одну особенность. В ущерб более ценным ссылкам таким генератором формируются ссылки вида:

.../ray-ban-kupit-ochki-m-61.html?sort=1a&page=1
.../ray-ban-kupit-ochki-m-61.html?sort=2d&page=1
.../ray-ban-kupit-ochki-m-61.html?sort=3a&page=1
.../ray-ban-kupit-ochki-m-61.html?sort=4a&page=1

Обратите внимание на фрагмент ?sort=1a&page=1 — это указывает на использование параметров сортировки и пагинации на странице. Заголовок такой страницы в разделе интернет-магазина при этом остаётся прежним — по названию категории или производителя (бренда). Как известно, поисковики чаще всего исключают из индексации страницы с одинаковыми заголовками и дублирующимся содержанием, поэтому такая ссылка, по всей вероятности, окажется бесполезной. Вспомним про лимит ссылок от генератора, и мы получаем картину, когда такие дубликаты заполняют пространство Sitemap вместо более значимых страниц сайта.

Создание динамического Sitemap на PHP: Обзор формата

С обоснованием актуальности разобрались. Пора приступить к делу. Я буду создавать файл карты сайта на PHP по аналогии с YML-файлом для трансляции товаров на Яндекс.Маркете.

Пробежимся по основным требованиям к файлу Sitemap.xml, рассмотрим элементы из XML-стандартов, используемые для его построения. Итак, простейший Sitemap будет выглядеть примерно так:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.example.com/</loc>
      <priority>0.8</priority>
   </url>
</urlset>

Как видим, здесь используется обязательный тег <loc> (ссылка) и один необязательный тег <priority> (указывает приоритетность страницы в диапазоне от 0.0 до 1.0). Другие необязательные теги, которые также можно применять: <lastmod> (дата последнего изменения, например, 2012-03-05), <changefreq> (периодичность изменения страницы: monthly, weekly, never, always и др.). Подробнее о формате файла Sitemap можно ознакомиться на официальном сайте.

Практическая реализация PHP-скрипта

В нашем PHP-скрипте создаём подключение к БД и определяем заголовок для вывода XML. Важное замечание: используется устаревшее расширение mysql_*. В новых проектах рекомендуется использовать mysqli или PDO.

<?php
/**************************************************
* Скрипт sitemap.php для индексации Yandex, Google и других поисковых ботов
* интернет-магазина на движке osCommerce 2.3
* Дата разработки: 30 августа 2012
* Разработчик: Володина Нина
* Сайт: www.codda.ru
*
* Скрипт распространяется по лицензии GNU.
* Вы можете использовать скрипт на свой страх и риск.
* За любые ошибки разработчики ответственности не несут.
**************************************************/

header('Content-Type: application/xml; charset=utf-8');

define('DB_HOST', ''); // Вписать сервер БД
define('DB_USER', ''); // Вписать имя пользователя
define('DB_PASS', ''); // Вписать пароль
define('DB_NAME', ''); // Вписать имя базы данных

$ctt = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die(mysql_error());
$db = mysql_select_db(DB_NAME) or die("Ошибка базы данных");
mysql_query("SET NAMES 'utf8'");

Так как таблицы хранятся в кодировке latin1, осуществляем запрос с заданной кодировкой (указано в последней строке). Я работаю с доработанной версией движка, в которой все URL являются ЧПУ (человеко-понятными урлами). Чтобы выдавать в карте сайта именно такие ссылки, создадим функцию транслитерации str_ru().

function str_ru($text) {
    $onetit = mb_strtolower($text, 'UTF-8');

    $trans = array(
        'к' => "k", 'а' => "a", 'б' => "b", 'в' => "v",
        'г' => "g", 'д' => "d", 'е' => "e", 'ё' => "e",
        'ж' => "j", 'з' => "z", 'и' => "i", 'й' => "y",
        'к' => "k", 'л' => "l", 'м' => "m", 'н' => "n",
        'о' => "o", 'п' => "p", 'р' => "r", 'с' => "s",
        'т' => "t", 'у' => "u", 'ф' => "f", 'х' => "h",
        'ц' => "c", 'ч' => "ch", 'ш' => "sch", 'щ' => "sch",
        'ь' => "", 'ъ' => "", 'ы' => "i", 'э' => "e",
        'ю' => "yu", 'я' => "ya", ' ' => "-", ' & ' => "-",
        '&' => "", '.' => "_"
    );

    $content = strtr($onetit, $trans);
    return $content;
}

Прописываем адрес сайта, начинаем формировать XML-структуру:

// Начинаем генерировать XML
$cdate = date("Y-m-d H:i", time());
$csite = "http://staroptic.ru/"; // Вписать адрес интернет-магазина

$yandex = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
';

Вручную прописываем три основных раздела сайта: Бренды, Новинки, Скидки, а также раздел со статьями.

// Статические важные страницы
$yandex .= "
<url>
    <loc>" . $csite . "ochki-linzi-opravi/kupit-ochki-brands.php</loc>
    <priority>0.9</priority>
</url>
<url>
    <loc>" . $csite . "ochki-linzi-opravi/novie-ochki.php</loc>
    <priority>0.7</priority>
</url>
<url>
    <loc>" . $csite . "ochki-linzi-opravi/ochki-so-skidkoy.php</loc>
    <priority>0.7</priority>
</url>
<url>
    <loc>" . $csite . "ochki-linzi-opravi/poleznoe-pro-ochki-t-2.html</loc>
    <priority>0.5</priority>
</url>
";

Теперь приступим к запросам к базе данных. Для начала выведем все категории и подкатегории.

// Выводим все категории и подкатегории
$arr_cats = array();
$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 = mysql_query($tmp);
while ($row = mysql_fetch_array($res)) {
    $row['name'] = htmlspecialchars($row['name']);
    $url = $csite . "ochki-linzi-opravi/" . str_ru($row['name']) . "-c-";
    if ($row['parent'] > 0) {
        $url .= $row['parent'] . "_";
    }
    $url .= $row['categoryID'] . ".html";

    $yandex .= "
<url>
    <loc>" . $url . "</loc>
    <priority>0.8</priority>
</url>
";

    $arr_cats[$row['categoryID']] = $row;
}

Теперь выведем все бренды (производителей).

// Выводим все бренды
$manufacturers_query = "SELECT manufacturers_name as name,
                               manufacturers_id as manufacturersID
                        FROM manufacturers
                        ORDER BY name";

$factres = mysql_query($manufacturers_query);
while ($brand = mysql_fetch_array($factres)) {
    $brand['name'] = htmlspecialchars($brand['name']);
    $url = $csite . "ochki-linzi-opravi/" . str_ru($brand['name']) . "-kupit-ochki-m-" . $brand['manufacturersID'] . ".html";

    $yandex .= "
<url>
    <loc>" . $url . "</loc>
    <priority>0.8</priority>
</url>
";
}

И, наконец, переходим к выводу товаров.

// Выводим все товары
$tmp = "SELECT p.products_id AS productID,
               pd.products_name AS name
        FROM products AS p,
             products_description AS pd
        WHERE p.products_price > 0
          AND pd.products_id = p.products_id
          AND p.products_status = 1
          AND pd.language_id = 2
        ORDER BY name";

$res = mysql_query($tmp);
while ($product = mysql_fetch_array($res)) {
    $product['name'] = htmlspecialchars($product['name']);
    $url = $csite . "ochki-linzi-opravi/" . str_ru($product['name']) . "-p-" . $product['productID'] . ".html";

    $yandex .= "
<url>
    <loc>" . $url . "</loc>
    <priority>0.6</priority>
</url>
";
}

В завершение скрипта закрываем XML-тег и выводим результат.

$yandex .= '
</urlset>';

// Выводим сгенерированный XML
echo $yandex;

?>

На выходе мы получили динамичный PHP-скрипт для создания карты сайта (Sitemap), предназначенной для лучшей индексации поисковиками. Наша карта включает все разделы (рубрики), бренды и товары. При этом при обновлении ассортимента интернет-магазина эти изменения будут автоматически отражаться в файле.

Оцените статью
codda