| ||
|
Почти универсална техника за странициране на резултати от БД.В този урок като ще видите как можете да си направите почти универсален страницатор. Какво ново в тук показаната реализация? Тук показаната реализация има следните по-важни черти: 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"; //Ах колко банално - да върнем резултата! 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-а който ще визуализира самите резултати с данни } // Живи ли сте още? Сега всеки път когато ви потрябва странициране просто е нужно да направите стъпките от 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' ];
|
|