Потребител Парола | Регистрация | Забравена парола
Меню
· Начало
· Файлове
· Форум
· Връзки
· Категории на уроците
· За контакти
· Фото галерия
· Търсене
Кажи на приятел

Вашия email:
email на приятел:
Копие за вас?
Реклама

Почти универсална техника за странициране на резултати от БД.

PHP & MySQLВ този урок като ще видите как можете да си направите почти универсален страницатор.

Какво ново в тук показаната реализация?
Тук показаната реализация има следните по-важни черти:
1. Почти универсална е
2. Ниска степен на повтаряемост на кода при повторна нужда
3. Лесна адаптация към сложни БД заявки с възможност за управление на сортирането и групирането на резултати.
4. Приложимост върху повече от един списъка едновременно.
5. Грижата за генерирането на навигатора за разходка между страниците вече няма да ви тормози.

Казвам, че е почти универсална, защото при свързване на таблици по някое поле, понякога логиката на сортирането на резултатите не може да се приложи в самата SQL заявка и сортирането трябва да се прави извън функцията която ще видите тук.

Описание на функцията
Функцията наречена pageQuery() се вика с три параметъра $qry, $pagenow, $perpage, като последния не е задължителен.
Първия параметър е асоциативен масив в който са зададени компонентите на заявката, както и някои други параметри управляващи процеса.
Втория и третия управляват текущата страница и броя резултати които да се показват на страница.

Идеята на функцията е да свърши цялата работа която винаги е еднаква при тази задача.
1. Първо се прави запитване към БД с което се уточнява колко редове общо отговарят на критерия по който търсим (ако изобщо търсим нещо)
2. На базата на този брой и променливата $perpage се изчисляват броя на страниците.
3. Конструира се LIMIT клауза
4. Конструира се навигатор от вида: <<Първа <Предишна [ 1 | 2 | 3 | 4 | 5 | 6 ] Следваща> Последна>>
5. Конструира се изходен масив.

Листинг на функцията (коментарите са важни)

//Някъде си имаме дефинирани константите:
define('ROWS_PREPAGE', 20);
define('DEFAULT_PAGER_NAME', 'pager');

function pageQuery($qry, $pagenow=1, $perpage=0)
{

// В началото валидираме стойностите на входните променливи $pagenow и perpage
// Ако със стойностите нещо не е наред тогава им задаваме тези по подразбиране

if(!is_int($pagenow) || !isset($pagenow) || $pagenow < 1) $pagenow = 1;
if(!is_int($perpage) || $perpage == 0) $perpage = ROWS_PREPAGE;

//Валидираме стойностите на масива съдържащ компонентите на заявката
if(!isset($qry['PAGER']) || $qry['PAGER'] == '') $qry['PAGER'] = DEFAULT_PAGER_NAME;

if(!isset($qry['WHERE']) || $qry['WHERE'] == '') $where = ' ';
else $where = " WHERE $qry[WHERE]";

if(!isset($qry['ORDERBY']) || $qry['ORDERBY'] == '') $order_by = ' ';
else $order_by = " ORDER BY $qry[ORDERBY]";

if(!isset($qry['GROUPBY']) || $qry['GROUPBY'] == '') $group_by = ' ';
else $group_by = " GROUP BY $qry[GROUPBY]";

//Изпълняваме заявка към БД с цел да уточним колко резултати удовлетворяват WHERE клаузата
$query = "SELECT COUNT(*) AS CNT FROM $qry[FROM] $where $group_by";
$row_count = mysql_result(mysql_query($query, __FILE__.': '.__LINE__));

//И изчисляваме в колко страници се вместват резултатите които ни интересуват
$page_count = ceil($row_count/$perpage); //Важно е да използвате ceil() !

//Проверяваме дали номера на исканата страница не превишава $page_count
//Ако да -> променяме номера й на $page_count
if($pagenow > $page_count) $pagenow = (int)$page_count;

//Следващия фрагмент конструира LIMIT клаузата на SQL
//заявката, както и низ който ще представи информация за резултатите
if(is_int($pagenow) && $pagenow > 0){
$limit = (($pagenow-1)*$perpage).','.($perpage);
$str_results = (($pagenow-1)*$perpage+1).' до '.min($row_count, ($pagenow*$perpage));
}else {
$limit = '0,'.$perpage;
$str_results = '1 до '.min($row_count, ($pagenow*$perpage));
}
$limit = 'LIMIT '.$limit;

//Ако случайно няма повече от 1 страница -> Отказваме се от LIMIT клаузата
if($page_count == 0 || $page_count == 1) $limit = '';


/*Долния фрагмент се грижи за съзвадането на навигатора, чрез който потребителите могат да преминават
от страница в страница. Тук можете да поставите всякаква логика, която удовлетворява вашия графичен дизайн
В случая навигатора е стандартен от типа:

<<Първа <Предишна [ 1 | 2 | 3 | 4 | 5 | 6 ] Следваща> Последна>>
*/

//генериране на Първа и Предишна. Внимаваме да не накараме Предишна да сочи извън диапазона
$navi_str = "<a href="some_url.com?$qry[PAGER]=1"><<Първа </a>";
if($pagenow > 1) $navi_str .= "<a href="some_url.com?$qry[PAGER]=".$pagenow-1.""> <Предишна </a>";
else $navi_str .= " <Предишна ";
//Номера на страниците. Текущата не е линк но е bold-ната
$separator = '';
for ($i=1; $i<=$page_count; $i++){
if($i != $pagenow) $navi_str .= "<a href="some_url.com?$qry[PAGER]=$i">$separator $i </a>";
else $navi_str .= "$separator <b>$i</b> ";
$separator = "|";
}
//генериране на Следваща и Последна. Отново внимаваме да не накараме Следваща да сочи извън диапазона
if($pagenow < $page_count) $navi_str .= "<a href="some_url.com?$qry[PAGER]=".$pagenow+1.""> Следваща> </a>";
else $navi_str .= " Следваща> ";
$navi_str .= "<a href="some_url.com?$qry[PAGER]=$page_count"> Последна>></a>";

//ВАЖНО: В горния фрагмент, е изключително важно да се генерират правилно рефернциите на линковете!
//За целта се използва GET променлива с име $qry['PAGER'] която указва коя страничка искаме да разгледаме
//при щракването на този линк =>
//Целта името да може да бъде сменяно е, че може да ни се наложи да разлистваме повече от един списък в една HTML страница
// ОТНОВО: Внимавайте много с URL-тата. Във вашия конкретен случай ще е различно от тук!!!

//Вече сме подготвени да конструираме изходния масив
//в който можем да сложим каквато информация решим, че би ни заинтересувала.

//Като за начало да подготвим заявката с LIMIT каузата чрез която фактически ще извлечем резултатите от БД
$res['QUERY'] = "SELECT $qry[SELECT] FROM $qry[FROM] $where $group_by $order_by $limit";

//Всякъква друга информация
$res['PAGECOUNT'] = $page_count;
$res['PAGENOW'] = $pagenow;
$res['PERPAGE'] = $perpage;
$res['ROWCOUNT'] = $row_count; //Това показва общия брой резултати
$res['NAVIGATOR'] = $navi_str;
$res['RESULTS_INFO'] = "Резултати от $str_results; Страница $pagenow от $page_count";

//Ах колко банално - да върнем резултата! Smile
return $res;
}

Използване
Сега да видим как можем да ползваме тази функция
Нека имаме някаква база данни с две таблици mastr_table и slave_table, като данните в двете се свързват по полето ID на master_table. Нека всички работи по канекцията към базата не ни интересуват. Сега за нас е важно следното:

//1. Като начало конструираме масив с компонентите на SQL заявката
$qry['SELECT'] = 'master_table.*, slave_table.*';
$qry['FROM'] = 'master_table, slave_table';
$qry['WHERE'] = 'master_table.ID>5 AND slave_table.MasterID = master_table.ID';
$qry['ORDERBY'] = 'master_table.ID DESC';
$qry['PAGER'] = 'articles_pager';
//2. Извикваме pageQuery();
$pgr_result = pageQuery($qry, (int)$HTTP_GET_VARS['articles_pager']);
//3. Взимаме си резултатите от Базата Данни
$result = mysql_query($pgr_result['QUERY']);
//4. И по най-стандартния начин обхождаме резултатите за да ги визуализираме
while ($row = mysql_fetch_array($result)){
//..като тук формираме HTML-а който ще визуализира самите резултати с данни
}

// Живи ли сте още? Smile

Сега всеки път когато ви потрябва странициране просто е нужно да направите стъпките от 1 до 4 показани по-горе.
Вече можете да сте независими от случая и когато ви потрябва странициране го имате в рамките на 40 секунди.

Някои неказани неща
1. $qry масива има следната структура
$qry['SELECT'] - съдържа информация за SELECT клаузата. Задължително трябва да присъства
$qry['FROM'] - съдържа информация за FROM клаузата. Задължително трябва да присъства
$qry [ 'WHERE' ] - съдържа информация за WHERE клаузата. Незадължителна
$qry [ 'ORDERBY' ] - съдържа информация за ORDER BY клаузата.Незадължителна
$qry [ 'GROUPBY' ] - съдържа информация за GROUP BY клаузата.Незадължителна
$qry [ 'PAGER' ] - името на странициращата GET поменлива. Използва се за генериране на линковете в навигатора. Елемента не е задължиелен.

2. Обърнете внимание как е повикана pageQuery() в стъпка 3. и по специално на $HTTP_GET_VARS[ 'xxxxx' ];

· ko6rata на January 19 2011 10:35:58 · 0 Коментари · 1322 Прочитания · Отпечатай
Коментари
Няма добавени коментари.
Напиши коментар
Моля влезте, за да коментирате.
Оценка
Рейтингите са достъпни само за регистрирани.

Моля влезте или се регистрирайте за да гласувате.

Няма оценки.
Вход
Потребител

Парола



Не сте регистрирани?
Натиснете тук за регистрация.

Забравена парола?
Натиснете тук за нова.
Анкета
С каква операционна система работите











Трябва да влезете за да гласувате.
ЧАТ
Трябва да влезате за да пуснете съобщение.

Няма съобщения.
Статистика