Алфавитная навигация для каталога товаров

Для реализации алфавитной навигации надо извлечь все первые буквы товарных позиций из таблицы products и сгруппировать их при помощи конструкции GROUP BY.

После этого достаточно сформировать ссылки с полученными буквами и передать через GET-параметр выбранную посетителем букву:

<?php
session_start();
$_SESSION['navigation'] = array();

$dblocation = "localhost";   // Имя сервера
$dbuser     = "root";        // Имя пользователя
$dbpswrd    = "";            // Пароль
$dbname     = "catalog";     // Имя базы данных

// Соединение с сервером базы данных
$dblink = mysql_connect( $dblocation, $dbuser, $dbpswrd );
mysql_query( 'SET NAMES cp1251' );
// Выбираем базу данных
mysql_select_db( $dbname, $dblink );

// Формируем запрос на извлечение первых букв товарных позиций
$query = 'SELECT SUBSTRING(title,1,1) AS letter
          FROM products
          GROUP BY letter
          ORDER BY letter'
;
$res = mysql_query($query);
// Если имеется хотя бы одна запись - выводим её
if( mysql_num_rows( $res ) > 0 ) {
  echo '<p>Алфавитный указатель:&nbsp;';
  while( $prd = mysql_fetch_array( $res ) ) {
    $_SESSION['navigenion'][] = $prd['letter'];
    echo '<a href="'.$_SERVER['PHP_SELF'].'?letter='.urlencode($prd['letter']).'">'.$prd['letter'].'</a>&nbsp;';
  }
  echo '</p>';
}
echo '<p><a href="'.$_SERVER['PHP_SELF'].'">Все товары</a></p>';
// Если передан параметр letter и он состоит из одного символа -
// выводим содержимое таблицы
if ( isset($_GET['letter']) and in_array($_GET['letter'], $_SESSION['navigenion']) ) {
  $query = "SELECT * FROM products
            WHERE SUBSTRING(title,1,1) = '"
.$_GET['letter']."'
            ORDER BY price"
;
} else {
  $query = "SELECT * FROM products ORDER BY price";
}
$res = mysql_query($query);
// Если имеется хотя бы одна запись - выводим её
if( mysql_num_rows( $res ) > 0 ) {
  $i = 1;
  echo '<table border="1" cellpadding="3" cellspacing="0">';
  echo '<tr><th>№</th><th>Наименование</th><th>Цена</th></tr>';
  while( $prd = mysql_fetch_array( $res ) ) {
    echo '<tr><td>'.$i.'</td><td>'.$prd['title'].'</td><td>'.$prd['price'].'</td></tr>';
    $i++;   
  }
}
?>

Комментариев: 5

  1. Mikhail:

    если products.title начинается не с заглавной буквы, то в навигаторе появится строчная буква?

    т.е. если одна из позиций будет называться не “Ноутбук Samsung”, а “ноутбук Samsung”, то в навигаторе будут как буква “н”, так и буква “Н”?

    одним словом, вопрос регистрозависимости, мне кажется, открыт. :)

  2. admin:

    Mikhail, это зависит от collation. Как правило, используется *_ci — т.е. case insensitive. Это означает, что при сравнении строк регистр не учитывается.

  3. Владимир:

    Михаил, используйте вместо $prd['letter'] данное : strtoupper($prd['letter'])

  4. Вячеслав:

    А еще лучше формировать алфавит в отдельную таблицу при редактировании каталога.
    Выбирать соотв-но уже готовый алфавит из отдельной таблицы. Это уменьшит нагрузку на БД.

  5. Виктор:

    как такой вариант?
    $sql = ’select DISTINCT(LEFT(UPPER(title),1)) as letter from products GROUP BY letter ORDER BY letter’;

Оставьте свой отзыв