Ierakstu dalīšana pa lappusēm
Jan21
Tēma šoreiz nav sareģīta, bet visur ir savs āķis.
Zināms, ka, lai izrēķinātu lappušu skaitu, jāzin kopējais ierakstu skaits, tātad divi pieprasījumi uz datubāzi:
- Iegūstam nepieciešamo skaitu ar ierakstiem
- Iegūstam kopējo ierakstu skaitu
Bet kur tad optimizācija? Un ja vēl nepieciešams liels skaits dinamiski ģenerētu filtru? Būs jāveido divi gandrīz identiski pieprasījumi – viens ar limitu, viens bez.
Es piedāvāju izmantot vienu no ne tik slavenajām MySQL funkcijām – SQL_CALC_FOUND_ROWS un FOUND_ROWS(). Pieprasījums un tā apstrāde, manā gadījumā, izskatīsies šādi:
1 2 3 4 5 6 7 8 9 10 11 12 | <? $perpage=10; // ieraksti vienā lappusē $_LIMIT=(!empty($_GET['p']) && $_GET['p']>1)?($_GET['p']*$perpage)-$perpage:0; // izrēķinam limita sākuma pozīciju, atkarīgā no atvērtās lappuses, kas padota kā ?p=X $_LIMIT.=", ".$perpage; $sql="SELECT SQL_CALC_FOUND_ROWS * FROM `tabula` LIMIT ".$_LIMIT; $res=mysql_query($sql); $count=mysql_fetch_object(mysql_query("SELECT FOUND_ROWS() as c")); while($row=mysql_fetch_object($res)){ var_dump($row); } $pages=splittopages($count->c,$perpage); ?> |
Funkcija, kura izrēķinās lappušu skaitu. Pieejamās lappuses tiek saliktas masīvā, lai būtu vienkāršāk izveidot pogas “Nākamā lappuse” un “Iepriekšējā lappuse” – atliek tikai pārbaudīt vai masīvā eksistē ieraksts ar atbilstošu atslēgu.
1 2 3 4 5 6 7 8 9 10 11 | <? function splittopages($count,$perpage){ $pagescount=ceil($count/$perpage); $pages=array(); if($pagescount<2){ return $pages; } for($i=1;$i<=$pagescount;$i++){ $pages[]=$i; } return $pages; } ?> |
Lappušu izvade.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | if($_GET['p']<2){ $_GET['p']=1; } // definēsim lappusi paši, ja tā vēl nav definēta $now=array_search($_GET['p'],$pages); // atvērtā lappuse $prev=$now-1; $next=$now+1; if(array_key_exists($prev,$pages)){ echo '<a href="?p='.$pages[$prev].'">Iepriekšējā lappuse</a>'; } foreach($pages as $value){ $active=$_GET['p']==$value?' class="active"':''; // atzīmējam atvērto lappusi echo '<a href="?p='.$value.'"'.$active.'>'.$value.'</a>'; } if(array_key_exists($next,$pages)){ echo '<a href="?p='.$pages[$next].'">Nākamā lappuse</a>'; } ?> |
Lielākais ieguvums izmantojot šādu risinājumu ir tāds, ka nav jāsūta vēl viens praktiski identisks pieprasījums uz datubāzi, ierakstu skaits jau tiek nokešots MySQL’ā.
Bez liekiem if’iem tiek pie nākamās un iepriekšējās lappuses.
21:39 on January 30th, 2009
Attiecībā uz SQL_CALC_FOUND_ROWS, šeit http://laacz.lv/2007/10/19/muzu-dzivo-muzu-macies/ jau komentāros aprunāts, ka ne vienmēr tas būs tas optimālākais variants.
14:41 on February 1st, 2009
Beigu beigās taču tika atzīts, ka šis strādā ātrāk par diviem selektiem, vai ne?
23:25 on February 6th, 2009
$count=mysql_fetch_object(mysql_query(”SELECT FOUND_ROWS() as c”));
Šito rindiņu pavisam noteikti var aizvietot ar kko šādu:
$count=mysql_num_rows($res);
Bet tā visā visumā man ar šito kodu sanāca ātrāk, paldies!
23:51 on February 6th, 2009
@duplets
Tā gan nevarēs, jo FOUND_ROWS() atgriež vienu ciparu, nevis ierakstu kaudzīti. mysql_num_rows() saskaita, cik ieraksti atgriezti.
23:57 on February 6th, 2009
uij, nē, bik sapinos meistarība, nemaz neiedziļinājos, ko tas tavs nodefinētais $count strings dara, mysql_num_rows nederēs… (BLUSH)
12:13 on February 7th, 2009
Eu itka man vis sanaca bet ka var uztaisit lai skripts paslep liekas lapas? jo man vinas loti daudz un tad tas lapu links ir izkroplots, ka noslept un tad taka lielaka dala laposanas skriptos uzradit pa lapai?
cerams ka sapratat manu domu!
14:44 on February 7th, 2009
Tak pakustini smadzenes, ciklā, kurā izvadi lapu linkus, nepieciešams viens vai divi if’i (pēc izvēles).
Ja konkrētās lapas numurs ir lielāks par, piemēram, 3 un mazāks par pēdējā lapa -3, tad šo izlaižam (iesaku lietot “continue;”).
14:51 on February 7th, 2009
@Mārcis
Nu kaut ko es sapratu bet nemaku pats izveidot jo nesmu vel tik pieredzejis tapec vai nevari iedot piemeru? tiesi kodu!
18:12 on June 24th, 2009
Sveicināti, bet man šis te iet tikai tad, ja es sekojošo rindu:
$sql=”SELECT SQL_CALC_FOUND_ROWS * FROM `tabula` “.$_LIMIT;
nomainu uz
$sql=”SELECT SQL_CALC_FOUND_ROWS * FROM `tabula` LIMIT $_LIMIT”;
21:08 on June 24th, 2009
druM, tā nevarētu būt, jo php sintakse pieļauj abus variantus, pirmais pat būtu ieteicamāks (tīri stila pēc).
13:34 on June 25th, 2009
Nu ja es lietoju pirmo variantu tad man nedarbojas mysql_fetch_object, uzmet kļūdu :/
15:26 on June 25th, 2009
Ja kļūdu izmet tikai pie mysql_fetch_object(), tad tā nav php sintakses kļūda, bet mysql sintakses kļūda.
Šādas problēmas nereti risina, apskatot kļūdas paziņojumu -
21:30 on June 25th, 2009
Bet es nevaru uzzināt kļūdu, jo pierakstot klāt mysql_error() man neko neizmet, tas varētu būt tādēļ ka .$_LIMIT ir aiz Pēdiņām…
Nu man tas kvērijs tad sanāk apmeram šāds:
$sql=”SELECT SQL_CALC_FOUND_ROWS * FROM `tabula` “.$_LIMIT OR DIE(mysql_error());
Viņam tādam arī ir jāizskatās ?
21:54 on June 25th, 2009
Šī raksta komentāri nav īstā vieta, kur mācīties elementārus php pamatus (sintaksi)… Turklāt es tev devu piemēru.
Bāžot visu ar karoti mutē, tu neko neiemācīsies.
Un ieslēdz tak error_reportingu, citādi neredzi arī sevis ielaistās kļūdas php kodā.
23:19 on June 25th, 2009
Labi, ceru uz turpmāko sadarbību caur e-mail
13:03 on June 26th, 2009
Cerība mirst pēdējā
Es, diemžēl, neesmu labdarības organizācija.
14:57 on September 6th, 2009
OMG Paldies tev mārci.. vis strādā perfekti.. liela buča tev
)
19:57 on September 12th, 2009
Hmm a kā uztaisīt lai izvadās visas lapas uzreiz nevis tikai nākamo rāda? nespēju saprast
20:08 on September 12th, 2009
Atvainojos tomēr viss ir.. biju izdēsis mainot kodu