Алфавитная навигация для каталога товаров
Для реализации алфавитной навигации надо извлечь все первые буквы товарных позиций из таблицы 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>Алфавитный указатель: ';
while( $prd = mysql_fetch_array( $res ) ) {
$_SESSION['navigenion'][] = $prd['letter'];
echo '<a href="'.$_SERVER['PHP_SELF'].'?letter='.urlencode($prd['letter']).'">'.$prd['letter'].'</a> ';
}
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++;
}
}
?>
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>Алфавитный указатель: ';
while( $prd = mysql_fetch_array( $res ) ) {
$_SESSION['navigenion'][] = $prd['letter'];
echo '<a href="'.$_SERVER['PHP_SELF'].'?letter='.urlencode($prd['letter']).'">'.$prd['letter'].'</a> ';
}
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++;
}
}
?>
Mikhail:
если products.title начинается не с заглавной буквы, то в навигаторе появится строчная буква?
т.е. если одна из позиций будет называться не “Ноутбук Samsung”, а “ноутбук Samsung”, то в навигаторе будут как буква “н”, так и буква “Н”?
одним словом, вопрос регистрозависимости, мне кажется, открыт.
17 Ноябрь 2008, 13:23admin:
Mikhail, это зависит от collation. Как правило, используется *_ci — т.е. case insensitive. Это означает, что при сравнении строк регистр не учитывается.
17 Ноябрь 2008, 14:07Владимир:
Михаил, используйте вместо $prd['letter'] данное : strtoupper($prd['letter'])
6 Июнь 2009, 22:07Вячеслав:
А еще лучше формировать алфавит в отдельную таблицу при редактировании каталога.
9 Июль 2009, 14:34Выбирать соотв-но уже готовый алфавит из отдельной таблицы. Это уменьшит нагрузку на БД.
Виктор:
как такой вариант?
31 Август 2010, 13:27$sql = ’select DISTINCT(LEFT(UPPER(title),1)) as letter from products GROUP BY letter ORDER BY letter’;