Лаборатория Кода, Маркетинг-Код

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

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

скрипт карты сайта sitemap xml на php

Конечно, для создания карты сайта всегда можно обратиться к генераторам Sitemap, благо, что в интернете существует много таких сервисов (нагуглить их по запросу «sitemap generator» не составит труда). Стоит лишь вбить адрес сайта в предлагаемое поле ввода, и для вас сгенерируется файл карты сайта Sitemap.xml по всем правилам. Сохраняете его на своем компьютере, переносите на сайт, а далее переходите в Яндекс.вебмастер и просто указываете ссылку на него. Однако, такой способ имеет ряд определённых недочётов. Во-первых, количество линков (url-ов вашего сайта), как правило, лимитируется генераторами в пределах от 500 до 1000. Т.е. для больших сайтов, с количеством страниц, превышающих тысячу, а то и несколько, такая карта сайта Sitepam.xml будет не полной. Во-вторых, если речь идет об интернет-магазине, в котором постоянно добавляются новые товары, безусловно, однажды созданная карта сайта не будет их включать. Для того, чтобы новые товары или любые изменения категорий были учтены в Sitemap.xml, нужно создать динамичный php-скрипт, который будет моделировать файл Sitemap.xml каждый раз при индексации сайта поисковиком.

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

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

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

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

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

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

<?xml version="1.0" encoding="UTF-8"?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

   <url>

      <loc>http://www.example.com/</loc>

      <priority>0.8</priority>

   </url>

</urlset>

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

В нашем PHP скрипте карты сайта Sitemap создаем подключение к БД и определяем формат передачи XML:

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

// Скрипт распространяется по лицензии GNU.
// Вы можете использовать скрипт на свой страх и риск. За любые ошибки разработчики отвественности не несут.
**************************************************/

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

$kurs=$currency_value[0];

  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 'latin1'");

Т.к. таблицы хранятся в кодировке latin1, осуществляем запрос mysql с заданной кодировкой (прописано в последней строке). Я работаю с тюнингованной версией движка (чит. Тюнинг osCommerce v.2.3, или прокачка интернет-магазина для дизайнерских и seo-целей), в которой все линки (url-ы) являются seo-оптимизированными и преображаются согласно семантики. Чтобы выдавать в карте сайта Sitemap именно такие ссылки на страницы, создадим функцию «str_ru». В полевых условиях хостинга и используемого файл-менеджера, мне удобнее конвертировать знаки из cp1251 (Windows-1251) в кодировку UTF-8 (что обеспечивается iconv). Однако, если вы делаете Sitemap.php в онлайновом файл-менеджере на сайте компании хостинга, можно сразу задать редактирование файла в UTF-8. Тогда конвертировать знаки не нужно. В этом случае, к каждому символу в массиве приводим («к» => «k», «а» => «a» и т.д.). Ниже сама функция:

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

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

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

Прописываем адрес сайта и начинаем шапку XML, открываем тег urlset:

#########################
# Начинаем генерировать XML
# переменные для заголовка
$cdate = date("Y-m-d H:i",time());
$csite = "http://staroptic.ru/";//Вписать адрес интернет-магазина
#----------------------------------------------
$yandex=<<<END
<?xml version="1.0" encoding="utf-8"?>
<urlset
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- created by N.Volodina, www.codda.ru , www.webmount.ru -->
<url>
  <loc>$csite
</loc>
</url>

END;

Вручную прописываем три стандартных области сайта, такие как: Бренды (Все производители), Новинки, Скидки (Спецпредложения). Т.к. сайт, который мной  оптимизировался, интернет-магазин очков STAROPTIC.RU, посвящен теме очков и очковых оправ, то используются заменённые названия файлов: kupit-ochki-brands.php (бывш. allmanufacturers.php), novie-ochki.php (бывш. products_new.php), ochki-so-skidkoy.php (бывш. specials.php). Четвертая ссылка — статьи (poleznoe-pro-ochki-t-2.html). Следует отметить, что сам движок находится в папке сайта «ochki-linzi-opravi/», и в данном скрипте наименование этого каталога будет фигурировать повсеместно.

$yandex .=   "<url>
  <loc>".
  $csite."ochki-linzi-opravi/kupit-ochki-brands.php
  </loc>
  <priority>0.9</priority>
</url>\n
<url>
  <loc>".
  $csite."ochki-linzi-opravi/novie-ochki.php
  </loc>
  <priority>0.7</priority>
</url>\n
<url>
  <loc>".
  $csite."ochki-linzi-opravi/ochki-so-skidkoy.php
  </loc>
  <priority>0.7</priority>
</url>\n
<url>
  <loc>".
  $csite."ochki-linzi-opravi/poleznoe-pro-ochki-t-2.html
  </loc>
  <priority>0.5</priority>
</url>\n";

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

$arr_cats=array();

#----------------------------------------------
    # выводим все подкатегории
        $yandex .= "\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 = mysql_query($tmp);
        while ($rezzzz = mysql_fetch_array($res)){
                #экранируем спецсимволы

                $rezzzz['name']=htmlspecialchars($rezzzz['name']);
                $fftt = "<url>\n  <loc>\n" . $csite. "ochki-linzi-opravi/". str_ru($rezzzz['name'])."-c-";

                if($rezzzz['parent']>0) $fftt .= $rezzzz['parent']."_";
                $fftt.= $rezzzz['categoryID'].".html\n  </loc>\n  <priority>0.8</priority>\n</url>\n";
                $yandex .= $fftt;

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

#----------------------------------------------

Теперь будем выводить все бренды:

    # выводим все бренды

$arr_fact=array();

$manufacturers_query =
"select manufacturers_name as name, manufacturers_id as manufacturersID
from
manufacturers
order by name";

   $factres = mysql_query($manufacturers_query);
        while ($rezfact = mysql_fetch_array($factres)){
                #экранируем спецсимволы

                $rezfact['name']=htmlspecialchars($rezfact['name']);
                $fftt_fct = "<url>\n  <loc>\n" . $csite. "ochki-linzi-opravi/". str_ru($rezfact['name'])."-kupit-ochki-m-".$rezfact['manufacturersID'].".html";

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

                $arr_fact[$rezfact['categoryID']]=$rezfact;
        }

$yandex .="\n\n";

#------------------------------------

Здесь следует оговориться, что сам линк на бренды немного модернизирован. Скажем, в интернет-магазине используется две версии подачи брендов. Если в товарах (навесной) применяется исключительно название бренда (например, Ray-Ban, Prada и т.д.), то на конкретной странице, посвящённой бренду, он имеет заголовок «Купить очки Ray-Ban«, «Купить очки Prada«. Соответственно этому заголовку, были построены и ссылки, т.е. к каждой из них, после названия, помимо указания бренда (-m-*manufacturersID) приписывается ещё и знаменатель «-kupit-ochki». Т.е. вид такого человеко-понятного урла (ЧПУ) в адресной строке будет следующим:

http://staroptic.ru/ochki-linzi-opravi/ray-ban-kupit-ochki-m-61.html

Я люблю последовательность во всём, и если в заголовок страницы бренда прописывается определённая связка (в данном случае, «Купить очки …»), она должна прослеживаться и в урле.

И, наконец, переходим к выводу товаров в нашей карте сайта Sitemap.php:

#----------------------------------------------
    # выводим все товары

$tmp="
        select
                p.products_id AS productID,
                p.products_status AS in_stock,
                pd.products_id,
                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 ($tovar = mysql_fetch_array($res)) {

        $valuta="RUR";//изменить на нужную валюту
        $price=$tovar[Price];

        $price=intval($price);

        $description=htmlspecialchars(strip_tags($tovar[brief_description]));

        $tovar['name'] = htmlspecialchars($tovar['name']);

        $srv = str_ru($tovar['name']);

#----------------------------------------------
$yandex.=<<<END
<url>
  <loc>
{$csite}ochki-linzi-opravi/{$srv}-p-$tovar[productID].html
  </loc>
  <priority>0.6</priority>
</url>

END;
}

В окончание, прописываем закрытие тега urlset, а дальше начинаем вывод того, что наскриптили:

$yandex .= "</urlset>";

#выводим, что нагенерили
echo $yandex;

?>

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

Этот материал опубликован в Лаборатория Кода, Маркетинг-Код и тегирован , , , , , , , , , , . Bookmark the permalink.

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

  1. pikasso говорит:

    Очень интересно…попробую поработать с вашим уроком …как раз остро стал вопрос карты сайта!…спасибо

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>